鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是經過鏈表中的指針連接次序實現的。node
鏈表由一系列結點(鏈表中每個元素稱爲結點)組成,結點能夠在運行時動態生成。數組
每一個結點包括兩個部分:一個是存儲數據元素的數據域,另外一個是存儲下一個結點地址的指針域。 相比於線性表順序結構,操做複雜。spa
因爲沒必要須按順序存儲,鏈表在插入的時候能夠達到O(1)的複雜度(注意這裏指的是鏈表在插入後,無需改變其餘元素的內存地址),比另外一種線性表(這裏指的是數組在某個位置插入後須要將該位置以後的元素都後移一位,所以複雜度爲O(n))快得多,可是查找一個節點或者訪問特定編號的節點則須要O(n)的時間,而有序的順序表相應的時間複雜度分別是O(logn)和O(1)。(前者指的是使用折半查找等方法,後者指的是直接用下標訪問數組元素)指針
鏈表的簡單實現及操做:
code
#include <stdio.h> #include <malloc.h> typedef struct node{ //定義節點類型 char data; //數據域 struct node *next; //指針域 }linklist; linklist* Create(){ //建立鏈表 char key; linklist *phead; //頭指針 linklist *pnew; //新節點 linklist *pend; //尾指針 phead = (linklist*)malloc(sizeof(linklist)); pend = phead; puts("請輸入你要建立的鏈表,以$結束"); key=getchar(); while(key!='$'){ pnew = (linklist*)malloc(sizeof(linklist)); pnew ->data = key; pend ->next = pnew; //新節點插入表尾 pend=pnew; //尾指針指向新表尾 key=getchar(); } pend->next = NULL; //將尾節點指向的下一節點設置爲空 return phead; //返回頭指針 } void Print(linklist *phead){ //打印鏈表 linklist *p = phead->next; while(p!=NULL){ printf("%c",p->data); p=p->next; } puts(""); } linklist* Get(linklist* phead,int pos){ //查找第pos個的節點 int cur = 0; //掃描器 linklist *p; p = phead; //指向頭節點 while((p->next!=NULL)&&(cur<pos)){ //不合法或到達尾部則退出 p = p->next; cur++; } return cur==pos?p:NULL; } int Locate(linklist* phead,char val){//查找值爲val的節點位置 int cur = 0,ok = 0; linklist *pnew = phead; while(pnew->next!=NULL){ if(pnew->data==val){ ok=1; break; } pnew=pnew->next; cur++; } return ok==1?cur:-1; } linklist *FindLocate(linklist *phead,int pos){ //查找倒數第K個節點的值 if(pos<=0) return NULL; //輸入不合法則返回 linklist *pnew = phead; pos--; while(pos--){ pnew = pnew -> next; } linklist *pnxt = phead; while(pnew->next!=NULL){ pnew = pnew -> next; pnxt = pnxt -> next; } return pnxt; } void DeleteAfter(linklist *p){ //刪除p的後繼節點 linklist *r; r = p->next; p->next = r->next; free(r); } void InsertAfter(linklist *p,char val){//插入p的後繼節點 linklist *pnew = (linklist*)malloc(sizeof(linklist)); if(p->next!=NULL){ pnew->next = p->next; }else{ pnew->next = NULL; } pnew ->data = val; p->next = pnew; } void Insert(linklist* phead,int pos,char val){//插入val到位置爲pos的節點以後 int cur=0; linklist* p = Get(phead,pos-1); if(p!=NULL){ InsertAfter(p,val); printf("插入成功!\n當前鏈表爲"); Print(phead); }else{ puts("插入錯誤!"); } } void Delete(linklist* phead,int pos){ //刪除位置爲pos的節點 int cur=0; linklist* p =Get(phead,pos-1); if(p!=NULL&&(p->next)!=NULL){ DeleteAfter(p); printf("刪除成功!\n當前鏈表爲"); Print(phead); }else{ puts("刪除錯誤!"); } } void Free(linklist*p){ //釋放鏈表 if(p->next!=NULL){ Free(p->next); } free(p); } int main(void){ linklist* phead = Create(); //頭指針 Print(phead); int pos; char val; puts("請輸入你要查找的位置"); scanf("%d",&pos); linklist* pfind = Get(phead,pos); if(pfind !=NULL){ printf("該位置值爲%c\n",pfind->data); } else{ puts("輸入錯誤!"); } puts("請輸入你要查找的值"); scanf(" %c",&val); int locate = Locate(phead,val); if(locate==-1){ puts("輸入錯誤!"); }else{ printf("該值位置爲%d\n",locate); } puts("請輸入你要查找的倒數第K個值"); scanf("%d",&pos); pfind = FindLocate(phead,pos); if(pfind !=NULL){ printf("倒數第K個數值爲%c\n",pfind->data); } else{ puts("輸入錯誤!"); } puts("請輸入你要刪除的位置"); scanf("%d",&pos); Delete(phead,pos); puts("請輸入你要插入的位置以及值"); scanf("%d %c",&pos,&val); Insert(phead,pos,val); Free(phead); return 0; }