鏈表基本操作及代碼實現(xiàn)

涉及到單鏈表的基本操作有如下:

int initList(linkList *);  //初始化一個單鏈表仪际,具有頭指針州既,頭結(jié)點浙值,頭結(jié)點->next=NULL;
int createListHead(linkList *, int n);  //頭插法創(chuàng)建一個鏈表陕凹,鏈表長度為n悍抑;
int createListTail(linkList *, int n);  //尾插法創(chuàng)建一個鏈表,鏈表長度為n杜耙;
int getlength(linkList *);  //獲取單鏈表的長度搜骡;
int printList(linkList *);  //打印整個鏈表;
int getElem(linkList *,int i,ElemType *);  //獲取鏈表中第i個位置處節(jié)點的數(shù)據(jù)元素佑女;
int insertList(linkList *, int i, ElemType data);  //在鏈表的指定位置(i節(jié)點)插入一個節(jié)點记靡,i的范圍為1~length(鏈表總長度);
int insertListTail(linkList *, ElemType data);  //給鏈表追加一個節(jié)點团驱,在最末尾處增加摸吠;
int deleteList(linkList *, int i, ElemType *data);  //刪除指定位置(i節(jié)點)處的節(jié)點,i的范圍為1~length(鏈表總長度)嚎花;
int clearList(linkList *);  //刪除整個鏈表寸痢,使頭結(jié)點->next=NULL;

(一)ADT:

[
復制代碼

](javascript:void(0); "復制代碼")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;">1 typedef int ElemType; 2 typedef struct Node { 3 ElemType data; 4 struct Node * next; 5 }Node; 6 typedef struct Node* linkList;</pre>

[
復制代碼

](javascript:void(0); "復制代碼")

*(二)初始化:int initList(linkList L)

[
復制代碼

](javascript:void(0); "復制代碼")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;">1 int initList(linkList L) 2 { 3 (L) = (linkList)malloc(sizeof(Node)); 4 (*L)->next = NULL; 5 printf("鏈表初始化成功\n"); 6 return 1; 7 }</pre>

[
復制代碼

](javascript:void(0); "復制代碼")

初始化一個指向頭節(jié)點的指針,使頭指針->next=NULL紊选,頭指針->data不做處理啼止;

image

(三)創(chuàng)建一個單鏈表

[
復制代碼

](javascript:void(0); "復制代碼")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;"> 1 int createListHead(linkList L,int n) { 2 linkList p;
3 int i = 0;
4 srand((int)time(0));
5 for (i = 0; i < n; i++)
6 {
7 p= (linkList)malloc(sizeof(Node));
8 p->data = rand() % 100;
9 printf("testing:Node[%d]=%d\n",i+1,p->data); 10 p->next = (
L)->next; 11 (*L)->next = p; 12 } 13 printf("鏈表(頭插法)創(chuàng)建成功\n"); 14 return 1; 15 }</pre>

[
復制代碼

](javascript:void(0); "復制代碼")

說明:

1道逗、圖中的head表示頭指針,而在創(chuàng)建單鏈表中的入?yún)head是指向指針的指針献烦;即phead等同于head滓窍,head指向頭節(jié)點;

2仿荆、初始化和創(chuàng)建整表的函數(shù)中贰您,為什么入?yún)⑹莑inkList *類型的參數(shù)呢,為什么不是Node 類型的拢操;之前我的理解是可以使用Node類型的入?yún)⒔跻啵@樣聲明一個Node *head,這樣在創(chuàng)建整表的函數(shù)中可以直接createList(head,10)令境,直接傳入頭指針杠园,但是嘗試過以后,會在通過頭指針訪問各節(jié)點數(shù)據(jù)的時候舔庶,彈出錯誤窗口抛蚁,原因還不太清楚;

3(補充)在看《C和指針》258的時候惕橙,看到了這么一句話瞧甩,好像可以解釋為什么需要傳入鏈表的基本操作函數(shù)中的入?yún)⑹且粋€指針類型的變量;

“i='a';pi='a';*ppi='a';  //這三條語句具有同樣的效果弥鹦;i-整型變量肚逸,pi-指向i的指針,ppi-指向pi指針的指針彬坏;

在一條簡單的對i賦值的語句就可以完成任務的情況下朦促,為什么還要使用更為復雜的涉及間接訪問的方法呢?這是因為簡單賦值并不總是可行栓始,例如鏈表的插入务冕。在那些函數(shù)中,我們無法使用簡單賦值幻赚,因為變量名在函數(shù)的作用域內(nèi)部是未知的禀忆。函數(shù)所擁有的只是一個指向需要修改的內(nèi)存位置的指針,所以要對該指針進行間接訪問操作以訪問需要修改的變量坯屿。

image
       ![image](http://upload-images.jianshu.io/upload_images/12754558-89b755976c4429a3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

[
復制代碼

](javascript:void(0); "復制代碼")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;">int createListTail(linkList L, int n) {
linkList p, temp;
temp = (
L); int i;
srand((int)time(0)); for (i = 0; i < n;i++) {
p = (linkList)malloc(sizeof(Node));
p->data = rand() % 100;
printf("testing:Node[%d]=%d\n", i + 1, p->data);
p->next = NULL;
temp->next = p;
temp = p;
}
printf("鏈表(尾插法)創(chuàng)建成功\n"); return 1;
}</pre>

[
復制代碼

](javascript:void(0); "復制代碼")

image

(四)獲取鏈表的長度

[
復制代碼

](javascript:void(0); "復制代碼")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;"> 1 int getlength(linkList L) {
2 linkList p;
3 int length=0;
4 p = (
L)->next;//p指向第一個節(jié)點油湖;
5 while (p) { 6 length++;
7 p = p->next;
8 }
9 return length; 10 }</pre>

[
復制代碼

](javascript:void(0); "復制代碼")

(五)打印整個鏈表

[
復制代碼

](javascript:void(0); "復制代碼")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;"> 1 int printList(linkList L) {
2 linkList p;
3 int i = 0;
4 p = (
L)->next;//p指向第一個節(jié)點;
5 printf("-----------打印整個鏈表-----------\n");
6 if (p==NULL) {
7 printf("這是一個空鏈表.\n");
8 }
9 while (p) { 10 i++; 11 printf("第%d個節(jié)點的數(shù)據(jù)data為=%d\n",i,p->data); 12 p = p->next; 13 } 14 return 1; 15 }</pre>

[
復制代碼

](javascript:void(0); "復制代碼")

(六)獲取指定位置處的節(jié)點元素领跛;

[
復制代碼

](javascript:void(0); "復制代碼")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;"> 1 int getElem(linkList *L, int i, ElemType getdata) {
2 linkList p;
3 p = (
L)->next;
4 if (p == NULL) 5 {
6 printf("鏈表為空乏德,請創(chuàng)建一個鏈表\n");
7 *getdata = -1;
8 return 0;
9 } 10 if (i < 1) 11 { 12 printf("您所查詢的節(jié)點%d,應該大于0,請重新輸入查詢\n",i); 13 *getdata = -1; 14 return 0; 15 } 16 int j = 1; 17 while (p&&j<i) { 18 j++; 19 p = p->next; 20 } 21 if (p == NULL) 22 { 23 printf("您所查詢的節(jié)點%d喊括,已經(jīng)超出了數(shù)組的長度\n",i); 24 *getdata = -1; 25 return 0; 26 } 27 *getdata = p->data; 28 printf("查詢成功胧瓜!\n", i); 29 return 1; 30 }</pre>

[
復制代碼

](javascript:void(0); "復制代碼")

(七)插入節(jié)點;

插入節(jié)點分為兩種郑什,一種是在鏈表的長度范圍內(nèi)插入節(jié)點府喳,第二種是在鏈表的尾部追加一個節(jié)點;

假設鏈表的長度為10蘑拯,第一種可以在1-10位置處插入節(jié)點钝满,比如在第10個位置插入一個節(jié)點,則原先的第10節(jié)點變?yōu)榱?1節(jié)點申窘,但是第二種是所有節(jié)點位置都不變弯蚜,在第11個位置追加一個新的節(jié)點;

[
復制代碼

](javascript:void(0); "復制代碼")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;"> 1 int insertList(linkList L, int i, ElemType data) 2 {
3 linkList p;
4 linkList insNode;
5 p = (
L);
6 int j=0;
7 // 鏈表為空剃法,在第1個位置插入一個新的節(jié)點碎捺;
8 if (p ->next == NULL) { 9 printf("鏈表為空,默認在第一個位置插入一個節(jié)點.\n"); 10 insNode = (linkList)malloc(sizeof(Node)); 11 insNode->data = data; 12 insNode->next = p->next; 13 p->next = insNode; 14 printf("節(jié)點插入成功.\n"); 15 return 1; 16 } 17 // 鏈表非空的情況下贷洲,可以在i=1~length的位置插入節(jié)點收厨,如果超過了鏈表的長度,就會提示錯誤优构; 18 // 其實如果在length+1的位置處插入一個新節(jié)點诵叁,就相當于在尾部追加一個節(jié)點,在本函數(shù)中會報錯钦椭,可以單獨實現(xiàn)一個函數(shù)黎休;
19 while(p && j<i-1) 20 { 21 j++; 22 p = p->next; 23 //printf("j=%d\tp->data=%d\n", j, p->data);
24 } 25 if (p->next==NULL) { 26 printf("您要插入的位置,超過了鏈表的長度 %d玉凯,請重新操作!\n",j); 27 return 0; 28 } 29 insNode = (linkList)malloc(sizeof(Node)); 30 insNode->data = data; 31 insNode->next = p->next; 32 p->next = insNode; 33
34 printf("節(jié)點插入成功\n"); 35 return 1; 36 }</pre>

[
復制代碼

](javascript:void(0); "復制代碼")

追加節(jié)點联贩;

[
復制代碼

](javascript:void(0); "復制代碼")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;"> 1 int insertListTail(linkList L, ElemType data)
2 {
3 linkList temp;
4 linkList p=(
L);
5 while(p) {
6 temp = p; 7 p = p->next;
8 }
9 p = (linkList)malloc(sizeof(Node)); 10 p->data = data; 11 p->next = NULL; 12 temp->next = p; 13 printf("節(jié)點插入成功\n"); 14 return 1; 15 }</pre>

[
復制代碼

](javascript:void(0); "復制代碼")

(八)刪除節(jié)點漫仆;

[
復制代碼

](javascript:void(0); "復制代碼")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;"> 1 int deleteList(linkList *L, int i, ElemType data)
2 {
3 linkList p,pnext;
4 int j = 0;
5 p = (
L);
6 if (p->next == NULL) { 7 printf("鏈表為空,無法刪除指定節(jié)點.\n");
8 *data = -1;
9 return 0; 10 } 11 while (p->next && j<i-1) { 12 j++; 13 p = p->next; 14 //printf("j=%d\t p->data=%d\n",j,p->data);
15 }//條件最多定位到最后一個節(jié)點泪幌;
16 if ( p->next == NULL) { 17 printf("您要刪除的節(jié)點盲厌,超過了鏈表的長度 %d,請重新操作祸泪!\n", j); 18 *data = -1; 19 return 0; 20 } 21 pnext = p->next; 22 p->next = pnext->next; 23 *data = pnext->data; 24 free(pnext); 25 printf("節(jié)點刪除成功\n"); 26 return 1; 27 }</pre>

[
復制代碼

](javascript:void(0); "復制代碼")

(九)刪除這個鏈表吗浩;

[
復制代碼

](javascript:void(0); "復制代碼")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;"> 1 int clearList(linkList L) {
2 linkList p, temp;
3 p = (
L)->next;//p指向第一個節(jié)點
4 while (p) { 5 temp = p; 6 p = p->next;
7 free(temp);
8 }
9 (*L)->next = NULL; 10 printf("整個鏈表已經(jīng)clear.\n"); 11 return 1; 12 }</pre>

[
復制代碼

](javascript:void(0); "復制代碼")

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市没隘,隨后出現(xiàn)的幾起案子懂扼,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阀湿,死亡現(xiàn)場離奇詭異赶熟,居然都是意外死亡,警方通過查閱死者的電腦和手機陷嘴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門映砖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人灾挨,你說我怎么就攤上這事邑退。” “怎么了劳澄?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵地技,是天一觀的道長。 經(jīng)常有香客問我浴骂,道長乓土,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任溯警,我火速辦了婚禮趣苏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘梯轻。我一直安慰自己食磕,他們只是感情好,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布喳挑。 她就那樣靜靜地躺著彬伦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伊诵。 梳的紋絲不亂的頭發(fā)上单绑,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機與錄音曹宴,去河邊找鬼搂橙。 笑死,一個胖子當著我的面吹牛笛坦,可吹牛的內(nèi)容都是我干的区转。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼版扩,長吁一口氣:“原來是場噩夢啊……” “哼废离!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起礁芦,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蜻韭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體湘捎,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡诀豁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了窥妇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舷胜。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖活翩,靈堂內(nèi)的尸體忽然破棺而出烹骨,到底是詐尸還是另有隱情,我是刑警寧澤材泄,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布沮焕,位于F島的核電站,受9級特大地震影響拉宗,放射性物質(zhì)發(fā)生泄漏峦树。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一旦事、第九天 我趴在偏房一處隱蔽的房頂上張望魁巩。 院中可真熱鬧,春花似錦姐浮、人聲如沸谷遂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肾扰。三九已至,卻和暖如春蛋逾,著一層夾襖步出監(jiān)牢的瞬間集晚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工区匣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留甩恼,地道東北人。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓沉颂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悦污。 傳聞我的和親對象是個殘疾皇子铸屉,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容