链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表
由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元
素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。
使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。在计算机科学中,链表作为一种基础的数据结构可以用来生成其它类型的数据结构。链表通常由一连串节点组成,每个节点包含任意的实例数据(datafields)和一或两个用来指向上一个/或下一个节点的位置的链接("links")。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。而链表是一种自我指示数据类型,因为它包含指向另一个相同类型的数据的指针(链接)。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。链表可以在多种编程语言中实现。像Lisp和Scheme这样的语言的内建数据类型中就包含了链表的存取和操作。程序语言或面向对象语言,如C,C++和Java依靠易变工具来生成链表。
下面附上一段由C语言实现的一个完整的单链表,包括创建,插入,删除,查询,排序,输出,获取链表长度,求有序链表交集,求有序链表差集,合并两条链表(两种方法)等功能:
#include<stdio.h> #include<malloc.h> typedef struct Node{ int data; struct Node* next; }Node; Node* AddNum(); /*创建链表*/ void Insert(Node* head,int i,int a); /*插入节点*/ void DeleteList(Node* head,int i); /*删除节点*/ void SerachList(Node* head,int a); /*查询数据*/ void SortList(Node* head); /*链表排序*/ Node* MergeList_old(Node* Ha,Node* Hb); /*利用旧节点合并两条链表*/ Node* MergeList_New(Node* Ha,Node* Hb); /*创建新节点合并两条链表*/ int GetListLength(Node* head); /*获取链表长度*/ Node* GetTheSame(Node* head1,Node* head2); /*求有序链表交集*/ Node* GetTheDiffirent(Node* head1,Node* head2); /*求有序链表链表差集*/ void PrintNum(Node* head); /*输出链表*/ Node* AddNum(){ char ans='y'; Node* head=(Node*)malloc(sizeof(Node)); Node* pc=(Node*)malloc(sizeof(Node)); head=pc; while(ans!='n'&&ans!='N'){ Node* temp1=(Node*)malloc(sizeof(Node)); pc->next=temp1; pc=temp1; printf_s("begin to add the number."); scanf_s("%d",&pc->data); printf_s("do you want to countinue."); fflush( stdin ); ans=getchar(); } pc->next=NULL; return head; } void Insert(Node* head,int i,int a){ int ai=0; Node* temp=(Node*)malloc(sizeof(Node)); temp=head; while(temp->next&&ai!=i-1){ temp=temp->next; ai++; } if(ai!=i-1){ printf_s("要插入的序号有误!!!"); } else{ Node* pc=(Node*)malloc(sizeof(Node)); pc->data=a; pc->next=temp->next; temp->next=pc; } } void DeleteList(Node* head,int i){ int ai=0; int a; Node* pc=(Node*)malloc(sizeof(Node)); Node* qc=(Node*)malloc(sizeof(Node)); pc=head; while(pc->next&&ai!=i-1){ pc=pc->next; ai++; } if(ai!=i-1||!pc->next) printf_s("错误的序号!!!"); else if(ai=i-1&&!pc->next) printf_s("错误的序号!!!"); else{ qc=pc->next; if(!qc->next){ a=qc->data; free(qc); printf_s("you delete the %d\n",a); } else{ pc->next=qc->next; a=qc->data; free(qc); printf_s("you delete the %d\n",a); } } } void SerachList(Node* head1,int a){ int i=0; Node* temp=(Node*)malloc(sizeof(Node)); temp=head1; while(temp->next&&temp->data!=a){ temp=temp->next; i++; } if(!temp->next) printf_s("没有此数据!!!"); else printf_s("在序号为%d的位置.",i); } void SortList(Node* head){ Node* pa=(Node*)malloc(sizeof(Node)); Node* pc=(Node*)malloc(sizeof(Node)); Node* temp=(Node*)malloc(sizeof(Node)); pa=head->next; while(pa){ pc=pa->next; while(pc){ if(pa->data>pc->data){ temp->data=pa->data; pa->data=pc->data; pc->data=temp->data; } pc=pc->next; } pa=pa->next; } } Node* MergeList_old(Node* Ha,Node* Hb){ Node* pa=(Node*)malloc(sizeof(Node)); Node* pb=(Node*)malloc(sizeof(Node)); Node* pc=(Node*)malloc(sizeof(Node)); pa=Ha->next; pb=Hb->next; pc=Ha; while(pa&&pb){ if(pa->data<=pb->data){ pc->next=pa; pc=pa; pa=pa->next; }else{ pc->next=pb; pc=pb; pb=pb->next; } } pc->next=pa?pa:pb; free(Hb); return Ha; } Node* MergeList_New(Node* Ha,Node* Hb){ Node* pa=(Node*)malloc(sizeof(Node)); Node* pb=(Node*)malloc(sizeof(Node)); Node* pc=(Node*)malloc(sizeof(Node)); Node* head=(Node*)malloc(sizeof(Node)); pa=Ha->next; pb=Hb->next; head=pc; while(pa||pb){ Node* tp=(Node*)malloc(sizeof(Node)); pc->next=tp; pc=tp; if(!pa){ pc->data=pb->data; pb=pb->next; } else if(!pb){ pc->data=pa->data; pa=pa->next; } else if(pa->data==pb->data){ pc->data=pa->data; pa=pa->next; pb=pb->next; } else if(pa->data<pb->data){ pc->data=pa->data; pa=pa->next; } else{ pc->data=pb->data; pb=pb->next; } } pc->next=NULL; return head; } int GetListLength(Node* head){ int i=0; Node* temp=(Node*)malloc(sizeof(Node)); temp=head; while(temp->next){ i++; temp=temp->next; } return i; } Node* GetTheSame(Node* head1,Node* head2){ Node* pa=(Node*)malloc(sizeof(Node)); Node* pb=(Node*)malloc(sizeof(Node)); Node* pc=(Node*)malloc(sizeof(Node)); pa=head1->next; pb=head2->next; pc=head1; while(pa&&pb){ if(pa->data==pb->data){ pc=pa; pa=pa->next; } else if(pa->data<pb->data){ pc->next=pa->next; free(pa); pa=pc->next; } else pb=pb->next; } pc->next=NULL; while(pa){ pc=pa; pa=pa->next; free(pc); } pb=head2; while(pb){ pc=pb; pb=pb->next; free(pc); } return head1; } Node* GetTheDiffirent(Node* head1,Node* head2){ Node* pa=(Node*)malloc(sizeof(Node)); Node* pb=(Node*)malloc(sizeof(Node)); Node* pc=(Node*)malloc(sizeof(Node)); pa=head1->next; pb=head2->next; pc=head1; while(pa&&pb){ if(pa->data==pb->data){ pc->next=pa->next; free(pa); pa=pc->next; } else if(pa->data<pb->data){ pc=pa; pa=pa->next; } else pb=pb->next; } pb=head2; while(pb){ pc=pb; pb=pb->next; free(pc); } return head1; } void PrintNum(Node* head){ Node* temp; temp=head; while(temp->next){ printf_s("%d",temp->next->data); temp=temp->next; } }
int main() { Node* head1; Node* head2; Node* head3; head3=NULL; head1=AddNum(); SortList(head1); head2 = AddNum(); SortList(head2); head3 = MergeList_old(head1, head2); PrintNum(head3); printf_s("\n"); return 0; }
数据结构学习笔记之链表(C语言版)