單鏈表,頭插法,尾插法各種函式詳解
阿新 • • 發佈:2018-11-09
一:LinkList.cpp檔案
#include <stdio.h> #include <malloc.h> //malloc函式 用了<stdlib.h>中的 <malloc.h>標頭檔案 typedef int ElemType; //自定義型別 使 ElemType 為 int型 typedef struct LNode //定義單鏈表結點型別 { ElemType data; struct LNode *next; //定義連結串列結點型別的指標 指向後繼結點 } LinkList; /* 連結串列中 不同對指標變數的不同引用的解釋 在main()函式裡 建立的是 LinkList *L; LinkLIst型別的指標變數 *L,變數L本身有地址, 作為指標變數也會儲存 指向元素的地址 如 L=(LinkList *)malloc(sizeof(LinkList)); //建立頭結點 L指向了 通過malloc 函式從記憶體裡動態獲取的一塊區域的 地址 在主函式讀取CreateListR(L,a,n);之前L沒有儲存地址不能用 *L 我的另外一篇轉載部落格 https://blog.csdn.net/Waybyway/article/details/83385551 在C語言裡沒有C++所謂的“按引用傳遞”,解釋了C 和C++ 的不同 連結串列所有改變連結串列函式長度的函式如 一: 頭插法,尾插法建立,初始化,銷燬,插入,刪除元素等函式用的引數是(LinkList *&L) *&L表示 *是間接運算子 對&L(L本身的地址)間接運算, 二:其他函式引數都是(LinkList *L) */ /*單鏈表 頭插法解釋 在主函式main()中 的指標Linklist *L用來建立連結串列; L為頭結點,首地址存在這個裡面了 L=(LinkList *)malloc(sizeof(LinkList)); //建立頭結點 在輸入之前現將他的指向置為 空NULL 通過malloc(sizeof(LinkList))動態分配sizeof(LinkList)的大小的空間 malloc函式的預設返還型別使 void型別,轉換成 (LinkList *)型別 這樣就建立了一個新結點 S s->data=a[i]; s結點的data值被賦值為 a[i]; 由於頭結點 L->next=NULL,所以 s->next=L->next; s->next 的指向也是NULL L->next=S; 頭結點 L指向了 第一個S (這個S記作 S_0) 這樣頭結點L就在 所有新結點的前面,最後使S_0結尾 指向為空 for(), 產生下一個 S_1 同樣 S_1 的data被賦值,s->next=L->next; 上一步 L指向 S_0即上一個 S,這樣S_1也指向了S_0 L->next=s; L這樣就指向了 S_1 總之 S_0指向空,新的 S結點指向前一個 S結點 頭結點L就在 所有新結點的前面,最後使S_0結尾 指向為空 最後生成的連結串列就是這樣 連結串列 數值序列是 陣列序列的逆序 L -> S_(N-1) -> S_(N-2) -> S_(N-3)……………… -> S_(1) -> S_(0) -> NULL */ void CreateListF(LinkList *&L,ElemType a[],int n) //頭插法建立單鏈表,將長度為N的陣列 a[]建立為連結串列 { LinkList *s;int i; L=(LinkList *)malloc(sizeof(LinkList)); //建立頭結點 L->next=NULL; for (i=0;i<n;i++) { s=(LinkList *)malloc(sizeof(LinkList));//建立新結點 s->data=a[i]; s->next=L->next; //將*s插在原開始結點之前,頭結點之後 L->next=s; } } /*尾插法,部分解釋與頭插法不再敘述 L為頭結點 ,指向為空 r=L; R 的指向也為空,R 的位置與L並列 產生新結點 S ,data被賦值為a[i] r->next=s; //將*s插入*r之後 R 的位置與L並列 頭結點L 指向 新產生的S結點 記作S_0 r=s; R 的位置與S_0並列 S_1產生 ,S_1的data被賦值 因為原來R與S_0並列,所以 r->next=s; 這樣S_0就指向了S_1 最後一個S_(n-1)產生,R與他並列 最後指向空NULL 總之 R指標每次與新產生結點並列,讓新結點指向下一個新結點 到最後一個結點 指向空 所以尾插法建立的連結串列 數值序列是 陣列序列 L -> S_(0) -> S_(1) -> S_(2)……………… -> S_(N-2)-> S_(N-1) -> NULL */ void CreateListR(LinkList *&L,ElemType a[],int n) //尾插法建立單鏈表 { LinkList *s,*r;int i; L=(LinkList *)malloc(sizeof(LinkList)); //建立頭結點 L->next=NULL; r=L; //r始終指向終端結點,開始時指向頭結點 for (i=0;i<n;i++) { s=(LinkList *)malloc(sizeof(LinkList));//建立新結點 s->data=a[i]; r->next=s; //將*s插入*r之後 r=s; } r->next=NULL; //終端結點next域置為NULL } void InitList(LinkList *&L) { L=(LinkList *)malloc(sizeof(LinkList)); //建立頭結點 L->next=NULL; } void DestroyList(LinkList *&L) { LinkList *p=L,*q=p->next; while (q!=NULL) { free(p); p=q; q=p->next; } free(p); //此時q為NULL,p指向尾結點,釋放它 } bool ListEmpty(LinkList *L) { return(L->next==NULL); } int ListLength(LinkList *L) { LinkList *p=L;int i=0; while (p->next!=NULL) { i++; p=p->next; } return(i); } void DispList(LinkList *L) { LinkList *p=L->next; while (p!=NULL) { printf("%d ",p->data); p=p->next; } printf("\n"); } bool GetElem(LinkList *L,int i,ElemType &e) { int j=0; LinkList *p=L; while (j<i && p!=NULL) { j++; p=p->next; } if (p==NULL) //不存在第i個數據結點 return false; else //存在第i個數據結點 { e=p->data; return true; } } int LocateElem(LinkList *L,ElemType e) { LinkList *p=L->next; int n=1; while (p!=NULL && p->data!=e) { p=p->next; n++; } if (p==NULL) return(0); else return(n); } bool ListInsert(LinkList *&L,int i,ElemType e) { int j=0; LinkList *p=L,*s; while (j<i-1 && p!=NULL) //查詢第i-1個結點 { j++; p=p->next; } if (p==NULL) //未找到位序為i-1的結點 return false; else //找到位序為i-1的結點*p { s=(LinkList *)malloc(sizeof(LinkList));//建立新結點*s s->data=e; s->next=p->next; //將*s插入到*p之後 p->next=s; return true; } } bool ListDelete(LinkList *&L,int i,ElemType &e) { int j=0; LinkList *p=L,*q; while (j<i-1 && p!=NULL) //查詢第i-1個結點 { j++; p=p->next; } if (p==NULL) //未找到位序為i-1的結點 return false; else //找到位序為i-1的結點*p { q=p->next; //q指向要刪除的結點 if (q==NULL) return false; //若不存在第i個結點,返回false e=q->data; p->next=q->next; //從單鏈表中刪除*q結點 free(q); //釋放*q結點 return true; } }
二:含有主函式的Exam2-6.cpp檔案
#include "linklist.cpp" void delmaxnode(LinkList *&L) { LinkList *p=L->next,*pre=L,*maxp=p,*maxpre=pre; while (p!=NULL) //用p掃描整個單鏈表,pre始終指向其前驅節點 { if (maxp->data<p->data) //若找到一個更大的節點 { maxp=p; //更改maxp maxpre=pre; //更改maxpre } pre=p; //p、pre同步後移一個節點 p=p->next; } maxpre->next=maxp->next; //刪除*maxp節點 free(maxp); //釋放*maxp節點 } int main() { LinkList *L; int n=10; ElemType a[]={1,3,2,9,0,4,7,6,5,8}; CreateListR(L,a,n); printf("L:");DispList(L); printf("刪除最大值節點\n"); delmaxnode(L); printf("L:");DispList(L); DestroyList(L); return 0; }
兩個檔案需要在同一資料夾下,否則需要標示路徑
今天就二級部落格了,surprise,連結串列學會了,看見成長了