数据结构——链表的操作
来源:互联网 发布:瓷砖设计软件手机版 编辑:程序博客网 时间:2024/05/21 13:23
这两天上课正好做到关于链表的一些操作,所以就把自己写的一些东西记录下来了
代码如下,不足之处望大家指正,旨在共同学习进步O(∩_∩)O~
#include <stdio.h>#include <stdlib.h>#include <time.h>//定义链表的结构体typedef struct node{int data;struct node *next;}node;//遍历输出链表void print(node *s){//利用一个中间节点来遍历链表并输出node *temp;temp=s->next;while(temp!=NULL){printf("%d ",temp->data);temp=temp->next;}printf("\n");}//查找元素void find(node *s,int destination){//利用一个中间节点来遍历链表并输出node *temp;temp=s->next;while(temp!=NULL){if(temp->data==destination){printf("存在该元素!\n");return;}temp=temp->next;} printf("不存在该元素!\n");printf("\n");}//插入节点node *add(node *s,int number){node *temp_list;for(int i=0;i<number;i++){if(temp_list==NULL){printf("error!\n");exit(1);}temp_list=(node *)malloc(sizeof(node));temp_list->data=rand()%100+1;temp_list->next=s->next;s->next=temp_list;}return s;}//删除节点node *del(node *s,int number){node *temp;for(int i=0;i<number;i++){//保存头结点指针域temp=s->next;//删除节点s->next=(s->next)->next;temp->next=NULL;//(s->next)->next=NULL;//s=s->next;}return s;}int main(void){//创建头结点node *head;node *list;srand(time(0));head=(node *)malloc(sizeof(node));//错误处理if(head==NULL)exit(1);head->next=NULL;//创建链表(头插法)list=(node *)malloc(sizeof(node));head->next=list;list->data=rand()%100+1;list->next=NULL;for(int i=0;i<9;i++){//错误处理if(list==NULL){printf("error!\n");exit(1);}list=(node *)malloc(sizeof(node));list->data=rand()%100+1;list->next=head->next;head->next=list;}print(head);////////////////////////////////////////////int operate;printf("请输入要执行的操作(1.插入,2.删除,3.查找,4.退出):");while(scanf("%d",&operate)==1){switch(operate){case 1:{ int add_number; printf("请输入要插入节点的个数:"); scanf("%d",&add_number); head=add(head,add_number); print(head); };break;case 2:{ int delete_number; printf("请输入要删除的节点个数:"); scanf("%d",&delete_number); head=del(head,delete_number); print(head); };break;case 3:{ int number; printf("请输入要查找的元素:"); scanf("%d",&number); find(head,number); };break;default:exit(1);}printf("请输入要执行的操作(1.插入,2.删除,3.查找,4.退出):");}free(head);free(list);return 0;}
以下是调试的结果(这里我用的都是随机的方法生成的数字):
继续上次的实验内容
这一次是添加了一个排序的功能(将两个链表合并之后进行升序的排列)
#include <stdio.h>#include <stdlib.h>#include <time.h>#define SWAP(a,b,c) ((c)=(a),(a)=(b),(b)=(c))//定义链表的结构体typedef struct node{int data;struct node *next;}node;void print(node *s){node *m;m=s->next;while(m!=NULL){printf("%-2d ",m->data);m=m->next;}printf("\n");}int main(void){//创建两个链表node *head1;node *head2;node *list1;node *list2;//创建表1head1=(node *)malloc(sizeof(node));head1->next=NULL;list1=(node *)malloc(sizeof(node));srand(time(0));list1->data=rand()%100+1;head1->next=list1;list1->next=NULL;for(int i=0;i<9;i++){list1=(node *)malloc(sizeof(node)); list1->data=rand()%100+1;list1->next=head1->next; head1->next=list1;}printf("表1内容:\n");print(head1);////////////////////////////////////////////////////////创建表2head2=(node *)malloc(sizeof(node));list2=(node *)malloc(sizeof(node));list2->data=rand()%100+1;head2->next=list2;list2->next=NULL;for(int j=0;j<9;j++){list2=(node *)malloc(sizeof(node)); list2->data=rand()%100+1;list2->next=head2->next; head2->next=list2;}printf("表2内容:\n");print(head2);/////////////////////////////////////////////////////////合并两个链表node *head3;head3=head1->next;while(head3!=NULL){if(head3->next==NULL){head3->next=head2->next;break;}head3=head3->next;}printf("合并之后的内容:\n");print(head1);/////////////////////////////////////////////////////////排序(选择排序)int temp;node *m=head1->next;node *n=NULL;while(m!=NULL){n=m->next;while(n!=NULL){if(m->data>n->data) SWAP(m->data,n->data,temp);n=n->next;}m=m->next;//n=m->next;}printf("排序之后的内容:\n");print(head1);///////////////////////////////////////////////////////free(head1);free(head2);free(head3);free(list1);free(list2); free(m); free(n);return 0;}
下面的运行结果(节点数我是一次性设置了十个,也可以自己修改一下,做一个任意设置的,数字也是随机生成的):
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
上面用的是头插法产生的链表,再输出的时候会差生一个问题(手动输入数据的话),就是反着输出来
所以现在用尾插法来修改一下,并且对之前不能在任意位置进行插入和删除节点也做了修改,具体的代码如下(新添加一个链表就地逆置的函数):
#include <stdio.h> #include <stdlib.h> int length;//链表的长度 typedef struct node{ int data; struct node *next; }node; #define SWAP(a,b,c) ((c)=(a),(a)=(b),(b)=(c)) ////////////////////////////////////// //创建链表(尾插法) node *create(node *s){ node *list,*p,*q; p=s; printf("请输入要建立的链表的长度:"); while(scanf("%d",&length)!=1); printf("请依次输入链表元素:\n"); list=(node *)malloc(sizeof(node)); p->next=list; scanf("%d",&list->data); list->next=NULL; for(int i=0;i<length-1;i++){ //临时节点 q=list; //申请新的节点 list=(node *)malloc(sizeof(node)); scanf("%d",&list->data); //前驱的指针域指向新的节点 q->next=list; //新节点的指针域置空 list->next=NULL; //list=q; } return s; } //////////////////////////////////////// //打印链表 void print(node *s){ node *p; p=s->next; while(NULL!=p){ printf("%-3d",p->data); p=p->next; } printf("\n"); } //////////////////////////////////////// //链表排序 void sort(node *s){ node *p,*q; p=s; int temp; while(NULL!=p){ q=p->next; while(NULL!=q){ if(p->data>q->data) SWAP(p->data,q->data,temp); q=q->next; } p=p->next; } } //////////////////////////////////////// //插入元素 node *insertion(node *s){ int number,pos; node *p;//记录插入位置的前驱 node *temp;//新插入的节点 p=s; temp=(node *)malloc(sizeof(node)); printf("请输入要进行插入的位置:"); //输入并做错误处理 while(scanf("%d",&pos)==1&&pos>=1&&pos<=length){ for(int i=1;i<pos;i++) p=p->next; printf("请输入插入的值:\n"); while(scanf("%d",&number)!=1); temp->data=number; temp->next=p->next; p->next=temp; break; } length++;//插入之后,链表长度加1 return s; } //////////////////////////////////////// //删除元素 node *_delete(node *s){ int pos; node *p,*q; p=s; printf("请输入要删除的位置:"); //错误处理 while(scanf("%d",&pos)!=1&&pos>length); for(int i=1;i<pos;i++){ //存储前驱 p=p->next; } //存下删除的位置 q=p->next; p->next=q->next; length--;//链表长度减1 return s; } //////////////////////////////////////// //查找元素 void search(node *s){ int number; node *temp=s->next; printf("请输入要查找的元素:"); while(scanf("%d",&number)!=1); while(NULL!=temp){ if(number==temp->data){ printf("存在该元素!\n"); return; } temp=temp->next; } printf("不存在该元素!\n"); return ; } //////////////////////////////////////// //就地逆序置换链表的函数 void transport(node *list) { node *p,*q,*s; //头指针不为空则进行置换 if(NULL != list) { //记录下首元素的节点和第二个节点 p = list->next; q = p->next; //头指针置空 list->next = NULL; //首元素置空,起始端做终点端 p->next = NULL; while(q) { //暂存下一个节点 s = q->next; //next域逆置 q->next = p; //指针后移 p = q; q = s; } list->next = p; } } //////////////////////////////////////// //销毁链表 void destory(node *s){ node *temp; node *q; temp=s->next; while(NULL!=temp){ //存储下一个节点 q=temp->next; //释放当前节点 free(temp);//节点后移一位 temp=q; } } //////////////////////////////////////// int main(void){ node *head; head=(node *)malloc(sizeof(node)); head->next=NULL; //创建链表 head=create(head); print(head); ///////////////////////////////////// //链表排序 int temp; printf("是否进行排序(1.是,2.否):"); scanf("%d",&temp); if(1==temp){ printf("排序之后如下所示:\n"); sort(head); print(head); } ///////////////////////////////////// int position; printf("请输入要进行的操作(1.插入,2.删除,3.查找,4.逆序置换,5.退出):"); while(scanf("%d",&position)==1){ switch(position){ case 1:head=insertion(head);print(head);break; case 2:head=_delete(head);print(head);break; case 3:search(head);break; case 4:transport(head);print(head);break; default:exit(0); } printf("请输入要进行的操作(1.插入,2.删除,3.查找,4.逆序置换,5.退出):"); } ///////////////////////////////////////////////////// //销毁链表 destory(head); free(head); return 0; }
运行结果截图:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
继续更新,这次是循环链表的操作,一个是建立一个循环链表,然后求出循环链表的长度(这里没有手动输入,手动输入的话稍微修改一下就行了),还有在首元素的节点之后插入一个新的节点的操作,代码如下:
#include <stdio.h>#include <stdlib.h>typedef struct node {int data;struct node *next;}node;void print(node *s){node *temp = s->next;do{printf("%-3d",temp->data);temp=temp->next;}while(s->next != temp);}//求循环链表的长度int f(node *s){int count = 0;node *temp = s->next;do{count ++;temp = temp->next;}while(s->next != temp);return count;}//表头插入节点void insert(node *s){int a;node *temp = s->next;node *insertion;insertion = (node *)malloc(sizeof(node));printf("请输入插入的元素:");scanf("%d",&a);insertion->data = a;insertion->next = temp->next;temp->next = insertion;}void destory(node *s){node *p = s->next,*q;//循环链表的终止条件要注意while(s->next != p){q = p->next;free(p);p = q;}}int main(int argc,char *args[]){node *head,*list,*p;head = (node *)malloc(sizeof(node));head->next = NULL;list = (node *)malloc(sizeof(node));head->next = list;list->data = 1;list->next = NULL;p = list;for(int i=1;i<=9;i++){list = (node *)malloc(sizeof(node));list->data = i+1;//链接新的节点p->next = list;list->next = NULL;//存储新节点作为下一节点的前驱p = list;}//终端端点链接首节点list->next = head->next;print(head);printf("\nThe length of the node table is:%d\n",f(head));insert(head);print(head);printf("\nThe length of the node table is:%d\n",f(head));destory(head);free(head);return 0;}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
课余时间继续更新,这次更新的是双向循环链表的相关操作(包括插入,删除,查找,以及创建一个和销毁一个双向循环链表的操作),由于双向循环链表的独特结构,所以在插入和删除操作的时间复杂度上都能达到常量级别,并且每个节点还有一个指针域指向自己的前驱,所以查找的话效率也会增加一些的,具体代码实现如下:
#include <stdio.h>#include <stdlib.h>typedef struct node {struct node *llink;int data;struct node *rlink;}node;void create(node *s){node *list,*temp;list = (node *)malloc(sizeof(node));list->data = 1;s->llink = NULL;s->rlink = list;list->rlink = NULL;for(int i = 2;i <= 10;i ++){//暂存一个节点temp = list;list = (node *)malloc(sizeof(node));list->data = i;list->llink = temp;temp->rlink = list;list->rlink = NULL;}list->rlink = s;s->llink = list;}void print(node *s){node *temp = s->rlink;while(s != temp){printf("%-3d",temp->data);temp = temp->rlink;}printf("\n");}void destory(node *s){node *p = s->rlink,*q = p->rlink;while(s != q){free(p);p = q;//暂存下一个节点q= q->rlink;}}void insert(node *s){int number;node *temp = s->rlink;node *newnode;newnode = (node *)malloc(sizeof(node));printf("请输入要插入的元素值:");while(scanf("%d",&number) != 1);newnode->data = number;newnode->rlink = temp->rlink;newnode->llink = temp;temp->rlink->llink = newnode;temp->rlink = newnode;}void del(node *s){node *temp = s->rlink;s->rlink = temp->rlink;s->rlink->llink = NULL;free(temp);}void search(node *s){int number;printf("请输入要查找的元素值:");while(scanf("%d",&number) != 1);node *temp = s->rlink;node *p = s->llink;//从双向链表的两端开始进行搜索while(p != temp){if(number == temp->data||number == p->data){printf("found!\n");return;}temp = temp->rlink;p = p->llink;}if(number == temp->data||number == p->data){printf("found!\n");return;}printf("not found!\n");}int main(int argc,char *args[]){node *head;head = (node *)malloc(sizeof(node));create(head);print(head);int pos;printf("请输入要执行的操作(1.插入,2.删除,3.查找,4.退出):");while(scanf("%d",&pos) == 1){switch(pos){case 1:insert(head);print(head);break;case 2:del(head);print(head);break;case 3:search(head);print(head);break;default:exit(0);}printf("请输入要执行的操作(1.插入,2.删除,3.查找,4.退出):");}destory(head);free(head);return 0;}
下面是调试的结果截图:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
有不足之处望大家指正,如果大家还有什么好的想法也可以提出来~~~
- 数据结构——链表的操作
- 数据结构—链表的操作小结
- 数据结构——双向链表的有关操作
- 数据结构——链表的基本操作
- 数据结构—(1)链表的基本操作
- 数据结构链表的操作
- 数据结构—单链表的操作
- 数据结构—双链表的操作
- 数据结构——单向链表操作
- 【巩固基础】数据结构——链表的操作:链表的创建和逆序操作
- 数据结构学习(七)——链队列的操作
- 数据结构学习(九)——链栈的操作
- 数据结构——链栈的基本操作
- 数据结构学习(一)——顺序表的操作
- 数据结构——顺序表的基本操作
- 数据结构——顺序表的基本操作
- 数据结构—线性表之顺序表的操作
- 数据结构 链表的基本操作
- 文字过长,QLabel显示不全的问题
- 网站抓取精灵V3.0正式版
- Java线程中run和start方法的区别
- 堆 和 栈的 区别
- 大整数乘法
- 数据结构——链表的操作
- hdu1542线段树+离散化+扫描线详解
- 高效工作——EA使用技巧
- 获取 ios 系统网络状况、电量
- Myeclipse8.5激活工具
- hdu 1060 Leftmost Digit
- 循环buffer解决网络通信中数据的不完整接收
- Android性能优化案例研究(下)
- ubuntu防火墙设置