1. 程式人生 > >鏈表插入和刪除,判斷鏈表是否為空,求鏈表長度算法的,鏈表排序算法演示——C語言描述

鏈表插入和刪除,判斷鏈表是否為空,求鏈表長度算法的,鏈表排序算法演示——C語言描述

如果 回收站 data 再次 http span 自己 getc tchar

關於數據結構等的學習,以及學習算法的感想感悟,聽了郝斌老師的數據結構課程,其中他也提到了學習數據結構的或者算法的一些個人見解,我覺的很好,對我的幫助也是很大,算法本就是令人頭疼的問題,因為自己並沒有學習過算法的系統性的課程,現在還是處於不斷摸索的階段,好多算法題目根本就沒有什麽思路,導致自己對好多題目都很是頭疼,就算是自己做過的一些算法的題目,再次遇到也還是不一定會做出來,他給出的建議就是,看懂別人的程序,然後自己去敲,一定會出錯,然後調試,有錯誤接著調試,一直到沒有錯誤為止,並且要時常的去復習自己敲過的代碼,這個過程註定是枯燥的,但卻是不得不經過的一個過程,一言難盡啊~,最後送自己三個字:註孤生.....

下面附上代碼:

  1 /*鏈表插入和刪除,判斷鏈表是否為空,求鏈表長度算法的,鏈表排序算法演示*/
  2 # include <stdio.h>
  3 # include <malloc.h>
  4 # include <stdlib.h>
  5 
  6 typedef struct Node
  7 {
  8     int data;//數據域
  9     struct Node * pNext;//指針域
 10 }NODE, *PNODE;//NODE等價於struct Node
 11 
 12               //
函數聲明 13 PNODE create_list(void); 14 void traverse_list(PNODE pHead); 15 bool is_empty(PNODE pHead); 16 int length_list(PNODE); 17 bool insert_list(PNODE, int, int);//要插入一個數據的話,要知道這個鏈表,再一個是位置,再一個是要刪除的元素 18 bool delete_list(PNODE, int, int *);//要刪除一個數據,要知道這個鏈表,再一個是位置,之所以定義了int * 型是因為要完成一個暫時的
19 //存儲,就像是實現回收站的功能一樣 20 void sort_list(PNODE); 21 22 int main(void) 23 { 24 int val; 25 PNODE pHead = NULL;//等價於 struct Node * pHead = NULL;把首節點的地址賦值給pHead(在一個鏈表中首節點和尾節點後面都是NULL,沒有其他元素) 26 //PNODE 等價於struct Node * 27 pHead = create_list(); 28 traverse_list(pHead); 29 printf("--------------------------------------\n"); 30 if (is_empty(pHead)) 31 printf("鏈表為空!\n"); 32 else 33 printf("鏈表不空!\n"); 34 printf("--------------------------------------\n"); 35 int len = length_list(pHead); 36 printf("鏈表的長度是%d\n", len); 37 printf("--------------------------------------\n"); 38 printf("重新排序之後:"); 39 sort_list(pHead); 40 traverse_list(pHead); 41 printf("--------------------------------------\n"); 42 printf("插入新的節點後為:"); 43 insert_list(pHead,3,33); 44 traverse_list(pHead); 45 printf("--------------------------------------\n"); 46 if (delete_list(pHead, 4, &val)) 47 { 48 printf("刪除成功,您刪除的元素是:%d\n", val); 49 50 } 51 else 52 { 53 printf("刪除失敗!您刪除的元素不存在!\n"); 54 } 55 traverse_list(pHead); 56 getchar(); 57 getchar(); 58 return 0; 59 } 60 61 //創建地址類型的地址,因為create_list 這個函數是要返回的地址 62 //功能就是把頭節點的地址返回,最終才能頭節點才能指向一個鏈表 63 PNODE create_list(void) 64 { 65 int len;//存放有效節點的個數 66 int i; 67 int val;//用來臨時存放用戶熟入的節點是值 68 69 //前面說過只要是找到頭節點,對於鏈表的操作就方便了,所以在這裏我們首先先定義頭節點 70 PNODE pHead = (PNODE)malloc(sizeof(NODE));//定義頭節點(不存放有效數據) 71 if (NULL == pHead) //如果指針指向為空,則動態內存分配失敗 72 { 73 printf("分配失敗,程序終止!\n"); 74 exit(-1); 75 } 76 PNODE pTail = pHead; //pHead 是指向頭節點的,如果用戶是輸入節點的個數是0,那麽只有一個“頭節點” 77 pTail->data = NULL; //此時把pHead 賦值給pTail,則就合理l,然後指針域為空(和初始化差不多...) 78 79 printf("請您輸入要生成鏈表節點的個數:len = "); 80 scanf("%d", &len); 81 for (i = 0; i < len; i++) 82 { 83 printf("請輸入第%d個節點的值", i + 1); 84 scanf("%d", &val); 85 PNODE pNew = (PNODE)malloc(sizeof(NODE));//創建新節點,使之指針都指向每一個節點(循環了len次) 86 if (NULL == pNew) //如果指針指向為空,則動態內存分配失敗 87 { 88 printf("分配失敗,程序終止!\n"); 89 exit(-1); 90 } 91 /* 92 93 pNew->data = val;//一個臨時的節點 94 pHead->pNext = pNew;//把pNew掛到pHead上 95 pNew->pNext=NULL; //這個臨時的節點最末尾是空 96 97 */ 98 99 100 //上面/**/註釋掉的這行代碼是有問題的,上面註釋掉的代碼的含義是分別把頭節點後面的節點都掛在頭節點上, 101 //導致頭節點後面的節點的指針域丟失,而我們想的是只是把第一個節點掛在頭節點上,後面的依次進行,即把第二個 102 //節點掛在第一個節點的指針域上,依次類推,很明顯上面所註釋掉的代碼是實現不了這個功能的 103 104 //下面是改進之後的 105 pNew->data = val; //把有效數據存入pNEW 106 pTail->pNext = pNew; //把pNew 掛在pTail的後面(也就是pTail指針域指向,依次串起來) 107 pNew->pNext = NULL;//把pNew的指針域清空 108 pTail = pNew; //在把pNew賦值給pTai,這樣就能循環,實現依次連接(而我們想的是只是把第一個節點掛在頭節點上,後面的依次進行,即把第二個 109 //節點掛在第一個節點的指針域上) 110 } 111 return pHead; 112 } 113 114 115 //遍歷函數並不需要返回值,參數還是要有的,要不然怎麽知道是對哪個對象進行的遍歷! 116 //還是定義指針變量 PNODE pHead 因為 traverse_list(pHead) 調用的是地址 117 118 119 /* 120 鏈表的遍歷寫法的整體思路: 121 1. 定義一個指針變量p指向第一個有效的節點 122 2.判斷這個節點的指針域是不是為空(如果不是就不是最後一個) 123 3.不為空就輸出此節點的有效數據,並且p-pNext來指向下一個節點(不能用p++哦!) 124 4.如果為空的話,說明到來尾節點 125 */ 126 127 128 void traverse_list(PNODE pHead)//怎樣遍歷,是不能像以前一樣用數組的,以為數組是連續的,這裏不連續 129 { 130 PNODE p = pHead->pNext; 131 132 while (NULL != p) 133 { 134 printf("%d ", p->data); 135 p = p->pNext; 136 } 137 printf("\n"); 138 } 139 140 /* 141 說明:_Bool依然仍是整數類型,但與一般整型不同的是,_Bool變量只能賦值為0或1,非0的值都會被存儲為1。 142 C99還提供了一個頭文件 <stdbool.h> 定義了bool代表_Bool,true代表1,false代表0。只要導入 stdbool.h , 143 就能非常方便的操作布爾類型了。 144 */ 145 146 147 //判斷鏈表是否為空的函數 148 bool is_empty(PNODE pHead) 149 { 150 if (NULL == pHead->pNext) 151 return true; 152 else 153 return false; 154 } 155 156 //鏈表長度計算函數 157 int length_list(PNODE pHead) 158 { 159 PNODE p = pHead->pNext; 160 int len = 0; 161 162 while (NULL != p) 163 { 164 ++len; 165 p = p->pNext;//鏈表不為空的時候,p就往下移一個 166 167 } 168 return len; 169 } 170 171 //排序函數 172 void sort_list(PNODE pHead) 173 { 174 int i, j, t, len = length_list(pHead); 175 PNODE p, q; 176 177 for (i = 0, p = pHead->pNext; i<len - 1; ++i, p = p->pNext) 178 { 179 for (j = i + 1, q = p->pNext; j<len; ++j, q = q->pNext) 180 { 181 if (p->data > q->data)// 類似於數組中的:a[i] >a[j] 182 { 183 t = p->data; //類似於數組中的:t = a[i]; 184 p->data = q->data; //類似於數組中的:a[i] = a[j]; 185 q->data = t; //類似於數組中的:a[j] = t; 186 } 187 } 188 } 189 190 191 return; 192 } 193 194 195 196 //插入函數 197 198 //在pHead 所指向鏈表的第pos個節點的前面插入一個新的結點,該節點的值是val,並且pos的值是從1開始的 199 bool insert_list(PNODE pHead, int pos, int val) 200 { 201 int i = 0; 202 PNODE p = pHead; 203 while (NULL != p && i < pos - 1) 204 { 205 p = p->pNext; 206 ++i; 207 } 208 if (i > pos - 1 || NULL == p) 209 return false; 210 PNODE pNew = (PNODE)malloc(sizeof(NODE));//在插入之前先分配一個動態內存空間 211 if (NULL == pNew) 212 { 213 printf("動態內存分配失敗!\n"); 214 exit(-1); 215 } 216 pNew->data = val; 217 PNODE q = p->pNext;//具體見93行附近註釋 218 p->pNext = pNew; 219 pNew->pNext = q; 220 221 return true; 222 223 224 } 225 226 //節點刪除函數 227 bool delete_list(PNODE pHead, int pos, int * pVal) 228 { 229 230 int i = 0; 231 PNODE p = pHead; 232 while (NULL != p->pNext && i < pos - 1) 233 { 234 p = p->pNext; 235 ++i; 236 } 237 if (i > pos - 1 || NULL == p->pNext) 238 return false; 239 PNODE q = p->pNext; 240 *pVal = q->data; //刪除之前先保存 241 242 //刪除p節點後面的節點 243 p->pNext = p->pNext->pNext; 244 free(q); 245 q = NULL; 246 return true; 247 } 248 249 /*對於排序函數的一個說明,其實是用了一個廣義的算法上的一個應用吧算是 250 算法: 251 狹義的算法是與數據的存儲方式密切相關 252 廣義的算法是與數據的存儲方式無關 253 泛型: 254 利用某種技術達到的 效果就是:不同的存數方式,執行的操作是一樣的 255 */

運行截圖:

技術分享

鏈表插入和刪除,判斷鏈表是否為空,求鏈表長度算法的,鏈表排序算法演示——C語言描述