C語言鏈表專題復習_第1頁
C語言鏈表專題復習_第2頁
C語言鏈表專題復習_第3頁
C語言鏈表專題復習_第4頁
C語言鏈表專題復習_第5頁
已閱讀5頁,還剩5頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

本文檔如對你有幫助,請幫忙下載支持!鏈表專題復習數組作為存放同類數據的集合,給我們在程序設計時帶來很多的方便,增加了靈活性。但數組也同樣存在一些弊病。如數組的大小在定義時要事先規定,不能在程序中進行調整,這樣一來,在程序設計中針對不同問題有時需要30個元素大小的數組,有時需要50個數組元素的大小,難于統一。我們只能夠根據可能的最大需求來定義數組,常常會造成一定存儲空間的浪費。我們希望構造動態的數組,隨時可以調整數組的大小,以滿足不同問題的需要。鏈表就是我們需要的動態數組。它是在程序的執行過程中根據需要有數據存儲就向系統要求申請存儲空間,決不構成對存儲區的浪費。鏈表是一種復雜的數據結構,其數據之間的相互關系使鏈表分成三種:單鏈表、循環鏈表、雙向鏈表,下面只介紹單向鏈表。單鏈表圖7-3是單鏈表的結構。單鏈表有一個頭節點 head,指向鏈表在內存的首地址。鏈表中的每一個節點的數據類型為結構體類型,節點有兩個成員:整型成員(實際需要保存的數據)和指向下一個結構體類型節點的指針即下一個節點的地址(事實上,此單鏈表是用于存放整型數據的動態數組)。鏈表按此結構對各節點的訪問需從鏈表的頭找起,后續節點的地址由當前節點給出。無論在表中訪問那一個節點,都需要從鏈表的頭開始,順序向后查找。鏈表的尾節點由于無后續節點,其指針域為空,寫作為NULL。圖7-3還給出這樣一層含義,鏈表中的各節點在內存的存儲地址不是連續的,其各節點的地址是在需要時向系統申請分配的,系統根據內存的當前情況,既可以連續分配地址,也可以跳躍式分配地址。看一下鏈表節點的數據結構定義:structnode{intnum;structnode*p;};p是指向與節點類型完全相在鏈表節點的定義中,除一個整型的成員外,成員同的指針。在鏈表節點的數據結構中,非常特殊的一點就是結構體內的指針域的數據類型使用了未定義成功的數據類型。這是在C中唯一規定可以先使用后定義的數據結構。單鏈表的創建過程有以下幾步:1)定義鏈表的數據結構。2)創建一個空表。3)利用malloc()函數向系統申請分配一個節點。4)將新節點的指針成員賦值為空。若是空表,將新節點連接到表頭;若是非空表,將新節點接到表尾。5)判斷一下是否有后續節點要接入鏈表,若有轉到 3),否則結束。單鏈表的輸出過程有以下幾步1)找到表頭。本文檔如對你有幫助,請幫忙下載支持!若是非空表,輸出節點的值成員,是空表則退出。3)跟蹤鏈表的增長,即找到下一個節點的地址。轉到2)。下列是用尾插法創建鏈表新開辟的節點總是插在表末[例7-5]創建一個存放正整數(輸入負數時做結束標志)的單鏈表,并打印輸出。#include<stdlib.h>/包*含malloc()的頭文件*/#include<stdio.h>structnode/*鏈表節點的結構*/{intnum;structnode*next; };main(){structnode*creat();/*函數聲明*/voidprint();structnode*head;/* 定義頭指針*/head=NULL;/*建一個空表*/head=creat(head);/*創建單鏈表*/print(head);/*打印單鏈表*/ }/******************************************/structnode*creat(structnode*head)函/數*返回的是與節點相同類型的指針*/{structnode*p1,*p2;p1=p2=(structnode*)malloc(sizeof(structnode)); 申請/*新節點*/scanf("%d",&p1->num);/* 輸入節點的值*/p1->next=NULL;/* 將新節點的指針置為空 */while(p1->num>0)/*輸入節點的數值大于 0*/{if(head==NULL)head=p1;/* 空表,接入表頭*/elsep2->next=p1;/*非空表,接到表尾*/p2=p1;p1=(structnode*)malloc(sizeof(structnode));申/請*下一個新節點*/scanf("%d",&p1->num);/*輸入節點的值*/}returnhead;/*返回鏈表的頭指針*/ }/*******************************************/voidprint(structnode*head) 輸/*出以head為頭的鏈表各節點的值 */{structnode*temp;temp=head;/*取得鏈表的頭指針*/while(temp!=NULL)/* 只要是非空表*/{printf("%6d",temp->num);/* 輸出鏈表節點的值*/本文檔如對你有幫助,請幫忙下載支持!temp=temp->next;/*跟蹤鏈表增長*/ } }在鏈表的創建過程中,鏈表的頭指針是非常重要的參數。因為對鏈表的輸出和查找都要從鏈表的頭開始,所以鏈表創建成功后,要返回一個鏈表頭節點的地址,即頭指針。下列是用頭插法創建鏈表新開辟的結點總是作為表頭結點程序清單位:#include<stdio.h>#include<stdlib.h>structnode{intnum;structnode*next;};structnode*creat(structnode*head){structnode*top;/*top為新開辟的結點*/top=(structnode*)malloc(sizeof(structnode));scanf(“%d”,&top->num);while(top->num>=0){top->next=head; /* 原來的第一個結點接在新開辟的結點后面 */head=top;/*新開辟結點作表頭結點,也就是說插在表頭*/top=(structnode*)malloc(sizeof(structnode));scanf(“%d”,&top->num); }returnhead; }單鏈表的插入與刪除在鏈表這種特殊的數據結構中,鏈表的長短需要根據具體情況來設定,當需要保存數據時向系統申請存儲空間,并將數據接入鏈表中。對鏈表而言,表中的數據可以依此接到表尾或連結到表頭,也可以視情況插入表中;對不再需要的數據,將其從表中刪除并釋放其所占空間,但不能破壞鏈表的結構。這就是下面將介紹的鏈表的插入與刪除。鏈表的刪除在鏈表中刪除一個節點,用圖 7-4描述如下:[例7-6]創建一個學生學號及姓名的單鏈表,即節點包括學生學號、姓名及指向下一個節點的指針,鏈表按學生的學號排列。再從鍵盤輸入某一學生姓名,將其從鏈表中刪除。首先定義鏈表的結構:從圖7-4中看到,從鏈表中刪除一個節點有三種情況,即刪除鏈表頭節點、刪除鏈表的中間節點、刪除鏈表的尾節點。題目給出的是學生姓名,則應在鏈表中從頭到尾依此查找各節點,并與各節點的學生姓名比較,若相同,則查找成功,否則,找不到節點。由于刪除的節點可能在鏈表的頭,會對鏈表的頭指針造成丟失,所以定義刪除節點的函數的返回值定義為返回結構體類型的指針。structnode*delet(structnode*head,char*pstr)/*head為頭指針,刪除 pstr所在節點*/{structnode*temp,*p;本文檔如對你有幫助,請幫忙下載支持!temp=head;/*鏈表的頭指針*/if(head==NULL)/* 鏈表為空*/printf("\nListisnull!\n");else/*非空表*/{temp=head;while(strcmp(temp->str,pstr)!=0&&temp->next!=NULL)/*若節點的字符串與輸入字符串不同,并且未到鏈表尾*/{p=temp;temp=temp->next;/* 跟蹤鏈表的增長,即指針后移 */}if(strcmp(temp->str,pstr)==0)/* 找到字符串*/{if(temp==head){/* 表頭節點*/printf("deletestring:%s\n",temp->str);head=head->next;free(temp);/*釋放被刪節點*/}else{p->next=temp->next;/*表中節點*/printf("deletestring:%s\n",temp->str);free(temp);} }elseprintf("\nnofindstring!\n"); /*沒找到要刪除的字符串

*/}return(head);/*返回表頭指針*/ }鏈表的插入首先定義鏈表的結構:struct{intnum;/*學生學號*/charstr[20];/*姓名*/structnode*next;};7-5所示。在建立的單鏈表中,插入節點有三種情況,如圖插入的節點可以在表頭、表中或表尾。假定我們按照以學號為順序建立鏈表,則插入的節點依次與表中節點相比較,找到插入位置。由于插入的節點可能在鏈表的頭,會對鏈表的頭指針造成修改,所以定義插入節點的函數的返回值定義為返回結構體類型的指針。節點的插入函數如下:structnode*insert(head,pstr,n)/*插入學號為n、姓名為pstr的節點*/structnode*head;/*鏈表的頭指針*/char*pstr;intn;{structnode*p1,*p2,*p3;本文檔如對你有幫助,請幫忙下載支持!p1=(structnode*)malloc(sizeof(structnode))分;配/*一個新節點*/strcpy(p1->str,pstr);/*寫入節點的姓名字串*/p1->num=n;/*學號*/p2=head;if(head==NULL)/* 空表*/{head=p1;p1->next=NULL;/* 新節點插入表頭*/}else{/*非空表*/while(n>p2->num&&p2->next!=NULL)/*輸入的學號小于節點的學號,并且未到表尾 */{p3=p2;p2=p2->next;/* 跟蹤鏈表增長*/}if(n<=p2->num)/*找到插入位置*/if(head==p2)/* 插入位置在表頭*/{head=p1;p1->next=p2;}else{/*插入位置在表中*/p3->next=p1;p1->next=p2;}else{/*插入位置在表尾*/p2->next=p1;p1->next=NULL;}}return(head);/* 返回鏈表的頭指針*/ }實例[例7-7]創建包含學號、姓名節點的單鏈表。其節點數任意個,表以學號為序,低學號的在前,高學號的在后,以輸入姓名為空作結束。在此鏈表中,要求刪除一個給定姓名的節點,并插入一個給定學號和姓名的節點。include"stdlib.h"include"malloc.h"structnode/*節點的數據結構*/{intnum;charstr[20];本文檔如對你有幫助,請幫忙下載支持!structnode*next;main()

};{/*函數聲明*/structnode*creat();structnode*insert();structnode*delet();voidprint();structnode*head;charstr[20];intn;head=NULL;/*做空表*/head=creat(head);/*調用函數創建以head為頭的鏈表*/print(head);/*調用函數輸出節點*/printf("\ninputinsertednum,name:\n");gets(str);/*輸入學號*/n=atoi(str);gets(str);/*輸入姓名*/head=insert(head,str,n); 將/*節點插入鏈表*/print(head);/*調用函數輸出節點*/printf("\ninputdeletedname:\n");gets(str);/*輸入被刪姓名*/head=delet(head,str);/調*用函數刪除節點*/print(head);/*調用函數輸出節點*/return; }/*** 創建鏈表************/structnode*creat(structnode*head){chartemp[30];structnode*pl,*p2;pl=p2=(structnode*)malloc(sizeof(structnode));printf("inputnum,name:\n;")printf("exit:doubletimesEnter!\n");gets(temp);gets(p1->str);pl->num=atoi(temp);pl->next=NULL;while(strlen(pl->str)>0{if(head==NULL)head=pl ;elsep2->next=p1;P2=pl;pl=(structnode*)malloc(sizeof(structnode));printf("inputnum,name:\n");printf("exit:doubletimesEnter!\n");本文檔如對你有幫助,請幫忙下載支持!gets(temp);gets(pl->str);p1->num=atoi(temp);p1->next=NULL;returnhead;}

}/********** 插入節點**********/structnode*insert(head,pstr,n);structnode*head;char*pstr;intn;{structnode*pl,*p2,*p3;p1=(structnode*)malloc(sizeof(structnode));strcpy(p1->str,pstr);p1->num=n;p2=head;if(head==NULL){head=pl;pl->next=NULL;}else{while(n>p2->num&&p2->next!=NULL){p3=P2p2=p2->next;}if(n<=p2->num)if(head==p2){head=pl;pl->next=p2;}else{p3->next=pl;pl->next=p2;}else{p2->next=pl;pl->next=NULL;}}return(head);}/***** 刪除節點*************/structnode*delet(structnode*head,char*pstr){structnode*temp,*p;structnode*p=head;本文檔如對你有幫助,請幫忙下載支持!temp=head;if(head==NULL)printf("\nListisnull!\n");else{temp=head;while(strcmp(temp->str,pstr)!=O&&temp->next!=NULL){p=temp;temp=temp->next,}if(strcmp(temp->str,pstr)==0){if(temp==head){head=head->next;free(temp);}else{p->next=temp->next;printf("deletestring:%s\n",temp->str);free(temp);} }elseprintf("\nnofindstring!\n");}return(head); }/********** 鏈表各節點的輸出

**********/voidprint(structnode*head){structnode*temp;temp=head;while(temp!=NULL){printf("\n%d----%s\n",temp->num ,temp->str);temp=temp->next ; }return; }帶頭結點與不帶頭結點鏈表的區別:題目中沒說明,就當不帶頭結點,除非明確規定了帶頭結點。帶頭結點的鏈表的第一個結點沒有數據域,只有指針域。例如要計算鏈表中所有結點數據的和,應定義一個指向結構體結點的指針,指向鏈表的第一個含數據的結點,給它賦值時,應是structnode*p=head->next;其中head為鏈表的頭指針。因為頭結點不含數據,頭結點指向的結點才開始帶數據。如果是不帶頭結點的鏈表,第一個結點就含數據,因此,給它賦值時,應是本文檔如對你有幫助,請幫忙下載支持!附:常見算法用鏈表實現查找算法例:如果有如下鏈表結構:structst{

charname[20];

/*

學生姓名

*/intcj;

/*

學生成績*/structst*next;};如果鏈表已創建正確,要求輸入一個學生姓名,查找該生成績,并輸出該生姓名,成績,以及該生

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論