练习题——线性表

一、编写一个由多个函数构成的完整程序,实现顺序表的建立、按照内容查找、插入、删除、显示操作。

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define MaxSize 20
typedef struct SeqList   //线性表顺序存储结构定义
{
    int elem[MaxSize];
    int length;
}SeqList;

int Init_SeqList(SeqList *L)  //顺序表初始化
{
    L->length=0;
    return 1;
}

int Locate_SeqList(SeqList *L,int x)   //按值查找
{
    int i=0;
    while(i<L->length&&L->elem[i]!=x)
        i++;
    if(i>=L->length)
     {
         printf("顺序表中不存在该元素!\n");
         return 0;
     }
     else
        return i+1;
}

int Insert_SeqList(SeqList *L,int i,int x)//在顺序表的第i个位置上插入元素x
{
    int j;
    if(L->length>=MaxSize)
        {printf("顺序表已满,无法插入!");return 0;}
    if(i<=0||i>L->length+1)
        {printf("插入位置不正确!");return 0;}
    for(j=L->length-1;j>=i-1;j--)
      {
        L->elem[j+1]=L->elem[j];
      }
        L->elem[i-1]=x;
        L->length++;
 return 1;
}

int Delete_SeqList(SeqList *L,int i)  //在顺序表中删除第i个元素
{
    int j;
    if(i<1||i>L->length)
      {
        printf("删除位置不正确!");
        return 0;
      }
    for(j=i;j<L->length;j++)
        L->elem[j-1]=L->elem[j];
     L->length--;
     return 1;
}

int Display_SeqList(SeqList L)  //显示顺序表
{
    int i;
    for(i=0;i<L.length;i++)
     {
        printf("%d",L.elem[i]);
     }
    return 1;
}

int main()
{
    SeqList L;
    int x;
    int i=1,k,j;
    Init_SeqList(&L);
    printf("初始化\n建立顺序表如下:");
    Insert_SeqList(&L,1,1);
    Insert_SeqList(&L,2,2);
    Insert_SeqList(&L,3,3);
    Insert_SeqList(&L,4,4);
    Display_SeqList(L);
    printf("\n");
    while(i<=3)
    {
        printf("\n        主菜单      \n");
        printf("   1   查找指定元素    \n");
        printf("   2   插入元素到指定位置   \n");
        printf("   3   删除某一指定位置元素  \n");
        printf("   0   结束程序            \n");
        printf("----------------------------\n");
        printf("请输入您选择的菜单号<1,2,3,0>:");
        scanf("%d",&i);
        switch(i)
        {
        case 1:
            printf("请输入查找元素: ");
            scanf("%d",&x);
            j=Locate_SeqList(&L,x);
            if(j!=0)
                printf("指定元素位置=%d\n",j);
            break;
        case 2:
            printf("请输入插入元素位置: "); scanf("%d",&k);
            printf("请插入元素值: ");   scanf("%d",&x);
            j=Insert_SeqList(&L,k,x);
            if(j!=0)
              {
                printf("插入后顺序表如下所示\n");
                Display_SeqList(L);
                printf("\n");
              }
            break;
        case 3:
            printf("请输入插入元素位置: ");
            scanf("%d",&k);
            j=Delete_SeqList(&L,k);
            if(j!=0)
            {
                printf("删除后顺序表如下所示:");
                Display_SeqList(L);
                printf("\n");
            }
            break;
        case 0:
            exit(0); break;
        default:
            printf("输出有误!");
        }
    }
    return 0;
}

二、建立一个顺序表,已知顺序表L中的元素为int,请写一时间复杂度O(n)、空间复杂度为O(1)的程序,将L中的数值为奇数的元素排在前面,数值为偶数元素排在后面。

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define MaxSize 5
typedef struct SeqList   //线性表顺序存储结构定义
{
    int elem[MaxSize];
    int length;
}SeqList;

void Init_SeqList(SeqList *L)  //顺序表初始化
{
    L->length=0;
}

void Insert_SeqList(SeqList *L,int i,int x)//在顺序表的第i个位置上插入元素x
{
    int j;
    if(L->length>=MaxSize)
        {printf("顺序表已满,无法插入!");}
    if(i<=0||i>L->length+1)
        {printf("插入位置不正确!");}
    for(j=L->length-1;j>=i-1;j--)
      {
        L->elem[j+1]=L->elem[j];
      }
        L->elem[i-1]=x;
        L->length++;
}

void Locate_SeqList(SeqList *L)//按位查找
{
    int i;
    int j=0;
    int k=0;
    for(i=0;i<MaxSize;i++)
    {
    if(L->elem[i]%2==1)
     {
        k=L->elem[i];
        L->elem[i]=L->elem[j];
        L->elem[j]=k;
        j++;
     }
    }
}

void Display_SeqList(SeqList L)  //显示顺序表
{
    int i;
    for(i=0;i<L.length;i++)
     {
        printf("%d",L.elem[i]);
     }
}

int main()
{
    SeqList L;
    Init_SeqList(&L);
    printf("初始化\n建立顺序表如下:");
    Insert_SeqList(&L,1,1);
    Insert_SeqList(&L,2,2);
    Insert_SeqList(&L,3,3);
    Insert_SeqList(&L,4,4);
    Insert_SeqList(&L,5,5);
    Locate_SeqList(&L);
    Display_SeqList(L);
    printf("\n");
    return 0;
}

三、建立一个非递减的顺序表L,已知顺序表L中的元素为int,请编写一个算法,删除所有值相等的多余元素。要求时间复杂度为O(n),空间复杂度为O(1)。

注:如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为O(1)

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define MaxSize 100
typedef struct SeqList   //线性表顺序存储结构定义
{
    int elem[MaxSize];
    int length;
}SeqList;

void Init_SeqList(SeqList *L)  //顺序表初始化
{
    L->length=0;
}

void Insert_SeqList(SeqList *L,int i,int x)//在顺序表的第i个位置上插入元素x
{
    int j;
    if(L->length>=MaxSize)
        {printf("顺序表已满,无法插入!");}
    if(i<=0||i>L->length+1)
        {printf("插入位置不正确!");}
    for(j=L->length-1;j>=i-1;j--)
      {
        L->elem[j+1]=L->elem[j];
      }
        L->elem[i-1]=x;
        L->length++;
}

void Delete_SeqList(SeqList *L)
{
   if(L->length==0)
    printf("不能删除!");
   int j=0;
   int i;
   for(i=1;i<L->length;i++)
   {
       if(L->elem[i]!=L->elem[j])
       {
           L->elem[++j]=L->elem[i];
       }
   }
   L->length=j+1;
}

void Display_SeqList(SeqList L)  //显示顺序表
{
    int i;
    for(i=0;i<L.length;i++)
     {
        printf("%d",L.elem[i]);
     }
}

int main()
{
    SeqList L;
    Init_SeqList(&L);
    printf("初始化\n建立顺序表如下:");
    Insert_SeqList(&L,1,1);
    Insert_SeqList(&L,2,2);
    Insert_SeqList(&L,3,3);
    Insert_SeqList(&L,4,3);
    Insert_SeqList(&L,5,4);
    Insert_SeqList(&L,6,4);
    Insert_SeqList(&L,7,5);
    Insert_SeqList(&L,8,6);
    Insert_SeqList(&L,9,7);
    Insert_SeqList(&L,10,8);
    Display_SeqList(L);
    printf("\n");
    Delete_SeqList(&L);
    Display_SeqList(L);
    return 0;
}

四、编写一个由多个函数构成的完整程序,实现单链表的初始化、建立、按照内容查找、插入节点、删除节点、显示整个链表的操作。

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define flag 0
typedef struct Lnode
{
    int data;
    struct Lnode *next;
}Lnode,*LinkList;//LinkList说明指针变量,强调它是某个单链表的头指针变量
//Lnode*来定义指向单链表中结点的指针
//Lnode和*LinkList不是变量名而是结构体类型的别名
Lnode *Get_LinkList(LinkList L,int i)//在带头结点单链表中查找第i个数据元素,找到返回其指针,否则返回空
{
    Lnode *p=L;//把p声明为一个可以使用Lnode结构体的结构体变量,p这个变量里就包含了Lnode结构体中所有的变量
    int j=0;
    while(p!=NULL&&j<i)
    {
        p=p->next;
        j++;
    }
    return p;//因为想返回指针,所以函数这样写成指针的形式
}
int Locate_LinkList(LinkList L,int x)
{
    LinkList p;
    int j=1;
    p=L->next;
    while(p!=NULL&&p->data!=x)
    {
        p=p->next;
        j++;
    }
    if(p)
    {
        printf("%d在链表中,是第%d个元素。\n",p->data,j);
        return j;
    }
    else
    {
        printf("该数值不在链表里。\n");
        return 0;
    }
}
int Insert_LinkList(LinkList *L,int i,int x)
{
    Lnode *p,*s;
    p=Get_LinkList((void*)L,i);//函数调用,查找第i位的结点
    if(p==NULL)
    {
        printf("参数i输入有误!\n");
        return 0;
    }
    else
    {
        s=(Lnode*)malloc(sizeof(Lnode));//申请、填装结点
        s->data=x;
        s->next=p->next;
        p->next=s;
        return 1;
    }
}
int Delete_LinkList(LinkList L,int i)
{
    LinkList p,s;
    p=Get_LinkList(L,i-1);
    if(p==NULL)
    {
        printf("待删结点前结点不存在!\n");
        return -1;
    }
    else if(p->next==NULL)
    {
        printf("该结点不存在!\n");
        return 0;
    }
    else
    {
        s=p->next;//s指向第i个结点
        p->next=s->next;//从链表中删除
        free(s);//释放s
        return 1;
    }
}
void Create_LinkList(LinkList *L,int n)//前插法创建带头结点单链表
{
    int i;
    LinkList p;
    *L=(LinkList)malloc(sizeof(Lnode));
    (*L)->next=NULL;//生成头结点
    for(i=n;i>0;--i)
    {
        p=(LinkList)malloc(sizeof(Lnode));//生成新结点
        p->data=i;
        p->next=(*L)->next;//将*p插入原开始结点之前,头结点之后
        (*L)->next=p;
    }
}
void Display_LinkList(LinkList L)
{
    LinkList p;
    p=L;
    while(p->next)
    {
        printf("%d",p->next->data);
        p=p->next;
    }
}
int main()
{
    printf("初始化\n建立单链表如下:\n");
    LinkList L;
    int x,y,cord,i;
    Create_LinkList(&L,4);
    Display_LinkList(L);
    do
    {
        printf("\n          主菜单         \n");
        printf("        1   尾插法插入元素到指定位置     \n");
        printf("        2   删除某一指定元素        \n");
        printf("        3   查找指定元素      \n");
        printf("        0   结束程序        \n");
        printf("------------------------------------\n");
        printf("请输入您选择的菜单号<1,2,3,0>:");
        scanf("%d",&cord);
        switch(cord)
        {
        case 1:
            printf("请输入插入元素位置前序号i:");
            scanf("%d",&x);
            printf("请输入插入的数据 y:");
            scanf("%d",&y);
            Insert_LinkList(&L,x,y);
            printf("单链表输出如下:\n");
            Display_LinkList(L);
            break;
        case 2:
            printf("请输入删除元素序号 x=?");
            scanf("%d",&x);
            Delete_LinkList(L,x);
            printf("单链表输出如下:\n");
            Display_LinkList(L);
            break;
        case 3:
            printf("请输入查找元素值 x:");
            scanf("%d",&x);
            i=Locate_LinkList(L,x);
            break;
        case 0:
            exit(0);
            break;
        default:
            printf("输入有误!");
        }
    }while(cord<=3&&cord>=0);
    return 0;
}

五、建立一个单链表L,已知节点的data域为int,请设计一个尽可能高效的算法,查找链表倒数第K个位置的节点,并返回该节点的data域。

#include <stdio.h>
#include <stdlib.h>
typedef struct Lnode
{
    int data;
    struct Lnode*next;
}Lnode,*LinkList;

void Create_LinkList(LinkList *L,int n)//前插法
{
    int i;
    LinkList p;
    *L=(LinkList)malloc(sizeof(Lnode));
    (*L)->next=NULL;
    for(i=n;i>0;--i)
    {
        p=(LinkList)malloc(sizeof(Lnode));
        p->data=i;
        p->next=(*L)->next;
        (*L)->next=p;
    }
}

int finddata(LinkList L,int k)
{
    Lnode *p1,*p2;
    p1=L;
    p2=L;
    int i=0;
    while(p1->next)
    {
        if(i<k-1)
        {
            p1=p1->next;
            i++;
        }
        else
        {
            p1=p1->next;
            p2=p2->next;
        }
    }
    return p2->data;
}

void Display_LinkList(LinkList L)
{
    LinkList p;
    p=L;
    while(p->next)
    {
        printf("%d",p->next->data);
        p=p->next;
    }
}
int main()
{
    LinkList L;
    Create_LinkList(&L,8);
    Display_LinkList(L);
    printf("\n");
    int k;
    scanf("%d",&k);
    printf("%d",finddata(L,k));
    return 0;
}

六、给定一个单链表,给定两个整数left、right,将该链表的第left和第right个节点的这一部分反转,要求时间复杂度为O(n),空间复杂度为O(1)。

#include <stdio.h>
#include <stdlib.h>

typedef struct Lnode
{
    int data;
    struct Lnode*next;
}Lnode,*LinkList;

void Create_LinkList(LinkList *L,int n)//前插法
{
    int i;
    LinkList p;
    *L=(LinkList)malloc(sizeof(Lnode));
    (*L)->next=NULL;
    for(i=n;i>0;--i)
    {
        p=(LinkList)malloc(sizeof(Lnode));
        p->data=i;
        p->next=(*L)->next;
        (*L)->next=p;
    }
}

void changelist(LinkList L,int left,int right)
{
    Lnode *p,*q,*s;
    p=(Lnode*)malloc(sizeof(Lnode));
    q=(Lnode*)malloc(sizeof(Lnode));
    s=(Lnode*)malloc(sizeof(Lnode));
    p=L;
    int i=1;
    for(i=1;i<=right;i++)
    {
        p=p->next;
        if(i==left)
        {
            s->data=p->data;
            q=p;
        }
    }
    q->data=p->data;
    p->data=s->data;
}

void Display_LinkList(LinkList L)
{
    LinkList p;
    p=L;
    while(p->next)
    {
        printf("%d",p->next->data);
        p=p->next;
    }
}

int main()
{
    LinkList L;
    int num;
    scanf("%d",&num);
    Create_LinkList(&L,num);
    Display_LinkList(L);
    printf("\n");
    int left,right;
    scanf("%d",&left);
    scanf("%d",&right);
    changelist(L,left,right);
    Display_LinkList(L);
    return 0;
}

七、已知由如下单链表(a1,a2,a3,a4,…,an),要求编写一个时间复杂度为O(n),空间复杂度为O(1)的算法,将该单链表转换成如下结构(an,an-2,…,a4,a2,a1,a3, …,an-3,an-1)

#include <stdio.h>
#include <stdlib.h>
typedef struct Lnode
{
    int data;
    struct Lnode*next;
}Lnode,*LinkList;

void Create_LinkList(LinkList *L,int n)//前插法
{
    int i;
    LinkList p;
    *L=(LinkList)malloc(sizeof(Lnode));
    (*L)->next=NULL;
    for(i=n;i>0;--i)
    {
        p=(LinkList)malloc(sizeof(Lnode));
        p->data=i;
        p->next=(*L)->next;
        (*L)->next=p;
    }
}

void transform(LinkList L)
{
    int i=1;
    Lnode *p1,*p2,*s;
    p1=L->next;
    p2=p1->next;
    s=L->next;
    while(p2!=NULL)
    {
        if(i%2==1)
        {
            L->next=p2;
            p1->next=p2->next;
            p2->next=s;
            s=L->next;
            p2=p1->next;
            i++;
        }
        else
        {
            p1=p1->next;
            p2=p2->next;
            i++;
        }
    }
}

void Display_LinkList(LinkList L)
{
    LinkList p;
    p=L;
    while(p->next)
    {
        printf("%d",p->next->data);
        p=p->next;
    }
}
int main()
{
    LinkList L;
    int num;
    scanf("%d",&num);
    Create_LinkList(&L,num);
    Display_LinkList(L);
    printf("\n");
    transform(L);
    Display_LinkList(L);
    return 0;
}

八、对于一个双向链表,实现该链表的反转,要求时间复杂度为O(n),空间复杂度为O(1)

#include <stdio.h>
#include <stdlib.h>

typedef struct DLnode
{
    int data;
    struct DLnode *prior;
    struct DLnode *next;
}DLnode,*DLinkList;

void Create_DLinkList(DLinkList *L,int n)
{
    int i;
    DLinkList p;
    *L=(DLinkList)malloc(sizeof(DLnode));
    (*L)->next=NULL;
    (*L)->prior=NULL;
    for(i=n;i>0;--i)
    {
        p=(DLinkList)malloc(sizeof(DLnode));
        p->data=i;
        p->next=(*L)->next;
        (*L)->next=p;
        if(p->next!=NULL)
        {
            p->next->prior=p;
        }
        p->prior=*L;
    }
}

void Reverse(DLinkList *L)
{
    DLnode *p=(*L)->next;
    DLnode *q;
    (*L)->next=NULL;
    while(p!=NULL)
    {
        q=p->next;
        p->next=(*L)->next;
        p->prior=q;
        (*L)->next=p;
        p=q;
    }
}

void Display_DLinkList(DLinkList L)
{
    DLinkList p;
    p=L->next;
    while(p)
    {
        printf("%d",p->data);
        p=p->next;
    }
}

int main()
{
    DLinkList L;
    int num;
    scanf("%d",&num);
    Create_DLinkList(&L,num);
    Display_DLinkList(L);
    printf("\n");
    Reverse(&L);
    Display_DLinkList(L);
    return 0;
}

九、将一个循环链表表示的稀疏多项式分解成两个多项式,使得这两个多项式中各自仅含奇数项或者偶数项,要求空间复杂度为 O(1)。

#include <stdio.h>
#include <stdlib.h>

int num=0;

typedef struct cNode
{
	int data1;
	int data2;
	struct cNode *next;
}cNode,*CircleList;

void Initlist(CircleList *L)
{
	*L=(CircleList)malloc(sizeof(cNode));
	(*L)->next=*L;
}

void Create_CircleList(CircleList L)
{
	int i=0;
	cNode *p,*s;
	p=L;
	int a,b;
	while(i!=num)
	{
		scanf("%d%d",&a,&b);
		s=(cNode*)malloc(sizeof(cNode));
		s->data1=a;
		s->data2=b;
		p->next=s;
		p=s;
		i++;
	}
  p->next=L;
}

void Divide(CircleList L)
{
	cNode *p,*q,*s;
	int i=0;
	s=L;
	q=L->next;
	p=L;
	while(s->next!=L)
   	  {
		s=s->next;
		if(s->data2%2==0)
		{
			i++;
		}
      }
    while(i!=0)
     {
       if(q->data2%2==0)
        {
	    	p->next=q->next;
	    	q->next=L;
	    	s->next=q;
	    	s=q;
	    	q=p->next;
	    	i--;
        }
       else
          {
          	p=p->next;
          	q=p->next;
		  }

     }
}

void view(CircleList L)
{
	cNode *p;
	p=L->next;
	printf("奇数次多项式为:\n");
	int flag=0;
	while((p->data2)%2!=0)
	  {
	  	if(flag==0)
	  	  {
	  	  	printf("%dx^%d",p->data1,p->data2);
		  }
		else
	      {
			printf("+%dx^%d",p->data1,p->data2);
		  }
		p=p->next;
		flag++;
	  }
	printf("\n");
	printf("偶数次多项式为:\n");
	while(p!=L)
	{
		printf("%dx^%d",p->data1,p->data2);
		if(p->next!=L)
		  {
		  	printf("+");
		  }
		p=p->next;
	}
  printf("\n");
}
int main()
{
	CircleList L;
	Initlist(&L);
	printf("输入多项式的总个数:");
	scanf("%d",&num);
	printf("请依次输入每个单项式的系数、指数:");
	Create_CircleList(L);
	Divide(L);
	view(L);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值