数据结构实验 单链表

来源:互联网 发布:nba2k online球星数据 编辑:程序博客网 时间:2024/05/23 10:53

编写一个完整的程序,实现单链表的建立、插入、删除、输出等基本操作。

1)建立一个带头结点的单链表。

2)计算单链表的长度,然后输出单链表。

3)查找值为x的直接前驱结点q

4)删除值为x的结点。

5)把单向链表中元素逆置(不允许申请新的结点空间)。

6)已知单链表中元素递增有序,请写出一个高效的算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素),同时释放被删结点空间,并分析你的算法的时间复杂度(注意:minkmaxk是给定的两个参变量,他们的值可以和表中的元素相同,也可以不同)。

7)同(6)的条件,试写一高效的算法,删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同),同时释放被删结点空间,并分析你的算法时间复杂度。

(8)利用(1)建立的链表,实现将其分解成两个链表,其中一个全部为奇数,另一个全部为偶数(尽量利用已知的存储空间)。

(9)在主函数中设计一个简单的菜单,分别测试上述算法。

//因为没有要求输入的链表数据的数量,所以我用-1表示输入结束。//测试数据 1 2 3 4 5 6 -1//测试删除相同元素的数据 2 2 3 3 4 4 5 5#include<stdio.h>#include<stdlib.h>struct node{int data;node *next;};node *h,*h1,*h2;void Creatlist()//创建链表{node *s,*e;h=(node *)malloc(sizeof(node));s=(node *)malloc(sizeof(node));h->next=s;printf("请输入单链表数据:     ");scanf("%d",&s->data);e=h;while(s->data!=-1)//用-1表示链表输入终止{e=s;s=(node *)malloc(sizeof(node));scanf("%d",&s->data);e->next=s;}e->next=NULL;return ;}void Printlist(node *h)//输出链表{int count;node *s;s=h;count=0;while(s->next!=NULL)//先遍历一遍,用count记录链表的长度。{count++;s=s->next;}printf("单链表长度:           %d\n",count);if(count==0){printf("链表为空!\n");return ;}printf("单链表数据:           ");s=h;while(s->next!=NULL){s=s->next;printf("%d ",s->data);}printf("\n");return ;}void Findlist()//查找值为x的前驱结点{int x;node *s,*e;printf("请输入待查找的数值:   ");scanf("%d",&x);s=h->next;if(s->data==x){printf("%d没有前驱结点!\n",x);//x为第一个结点return ;}e=s->next;while(e->data!=x&&e->next!=NULL){s=e;e=s->next;}if(e->data!=x){printf("单链表中不存在值为%d的结点!\n",x);//链表中没有xreturn ;}printf("%d的前驱结点为:        %d\n",x,s->data);return ;}void Deletlist()//删除值为x的结点,实验中没有要求,我写的时候是按链表中只有一个值为x的结点。{int x;node *s,*e;printf("请输入需要删除的数值: ");scanf("%d",&x);s=h;e=s->next;while(e->data!=x&&e->next!=NULL){s=e;e=s->next;}if(e->data!=x){printf("单链表中不存在值为%d的结点!\n",x);//链表中没有值为x的结点return ;}s->next=e->next;free(e);return ;}void Inverlist()//逆置链表,将连接链表的指针方向倒转,不需要申请新的空间。{node *s,*e,*r;s=h->next;e=s->next;if(e==NULL){h->next=s;return ;}s->next=NULL;r=e->next;while(e!=NULL){e->next=s;s=e;e=r;if(e==NULL)break;r=e->next;}h->next=s;return ;}void Delexylist()//删除链表中x和y之间的数字,而且要求释放内存。既然要求释放内存,那就只能遍历,我没想到什么更高效的算法,因为链表是有序的,我释放到值为y结束。{int x,y;node *s,*e,*r;printf("请输入需要删除的区间   ");scanf("%d %d",&x,&y);r=h;s=h->next;while(s->data<=y&&s->next!=NULL){e=s->next;if(s->data>=x){free(s);r->next=e;}elser=s;s=e;}return ;}void DeleSamelist()//删除相同元素的结点同时释放内存空间。同样需要遍历,没有想到特别高效的算法。{int temp;node *s,*e,*r;r=h;s=h->next;if(s==NULL)return ;temp=-1;while(s!=NULL){e=s->next;if(s->data==temp){free(s);r->next=e;}else{temp=s->data;r=s;}s=e;}return ;}void Cutlist()//分拆链表。{node *s,*s1,*e1,*s2,*e2;h1=(node *)malloc(sizeof(node));s1=(node *)malloc(sizeof(node));h2=(node *)malloc(sizeof(node));s2=(node *)malloc(sizeof(node));e1=h1;e1->next=NULL;e2=h2;e2->next=NULL;s=h->next;while(s!=NULL){if(s->data%2!=0){s1->data=s->data;e1->next=s1;e1=s1;e1->next=NULL;s1=(node *)malloc(sizeof(node));}else{s2->data=s->data;e2->next=s2;e2=s2;e2->next=NULL;s2=(node *)malloc(sizeof(node));}s=s->next;//第一次写的时候没有加上这一句,电脑直接就卡死了。。。。}Printlist(h1);Printlist(h2);return ;}int Opra(){int T;printf("*****************目录******************\n");printf("创建一个单链表:                      1\n");printf("计算单链表长度并输出单链表:          2\n");printf("查找值为x的前驱结点:                 3\n");printf("删除值为x的结点:                     4\n");printf("把单链表中的元素逆置:                5\n");printf("删除单链表中值在x和y之间的元素:      6\n");printf("删除链表中值相同的元素:              7\n");printf("将链表分成两部分:                    8\n");printf("操作结束:                            0\n");printf("输入操作代号:         ");scanf("%d",&T);switch(T){case 1:Creatlist();break;case 2:Printlist(h);break;case 3:Findlist(); break;case 4:Deletlist();break;case 5:Inverlist();break;case 6:Delexylist();break;case 7:DeleSamelist();break;case 8:Cutlist();break;case 0:return 0;default :printf("输入错误,请重新输入!\n");break;}return 1;}int main(){int flag=1;while(1){flag=Opra();if(!flag)//用flag控制是否跳出循环。break;printf("\n\n");}printf("谢谢使用!\n");return 0;}


原创粉丝点击