// delete a node of data val in a link list void delete_specified_data(int val) { node *rush, *prev; rush = head; // search for data val while (rush != NULL && val != rush->val) { prev = rush; rush = rush->next; } // if there is no result if (rush == NULL) { printf("Data no found!\n"); exit(1); } // if that result is the first node, // then head will be the next node else if (rush == head) head = rush->next; // else, pull out the node else prev->next = rush->next; free(rush); }這個是只刪除某一個值,但是只刪除一個而已,因此如果一個數列23 54 54 34 65 12 在這邊如果刪除54的話,只會刪除第一個54。 所以概念上就是從link list之中從頭開始找,找到符合值為val的就把它刪除,刪除方式就是把他前面的node的next接它後面。接著再free掉它。
rush = head; // search for data val while (rush != NULL && val != rush->val) { prev = rush; rush = rush->next; }首先把探索用的指標rush initialize為head,接著迴圈內就開始找第一個符合我們要找的值的node為止。這時候rush有幾種情形
1. 第一個node就找到了
2. 沒有找到
3. 找到了,但不是1.的情形
while內的條件最好是該有正確的boundary判斷,因此rush != NULL,因為筆者的參考書沒有這一段,所以特別標明這一點。如果這個link list沒有找到我們要找的資料的話,那麼最後rush會跑到NULL上,接著會讀取不存在的記憶體rush = rush->next,這樣是有問題的。
所以當我們找到的是第1.的情形的時候,他會和第三個有所不同。因為第三個情形的處理方式就是該把(我們找到的node)前面那個的next給接到(我們找到的node)的後一個。但如果是第一個情形不會有前面那個node,這時候prev是沒有Initialize的所以一樣會讀取到沒有allocate的記憶體上。
else if (rush == head) head = rush->next; // else, pull out the node else prev->next = rush->next;所以第一個else if就是判斷第一個情形,這時候因為我們要移掉的是第一個node,處理方式就是重新指定head為後一個node就行了。而第三種情形的處理方式就是把前面那個node往後接給後面那一個node。
至於第二個情形
if (rush == NULL) { printf("Data no found!\n"); exit(1); }就該把沒找到的訊息印出來並且直接跳出去。筆者的參考書一樣沒這一段,雖然本身無關緊要。因為如果沒有找到的話,那麼我們最後要free()的時候便會free掉什麼都沒有的NULL,這本身是沒什麼問題的。但寫程式概念還是要清楚,畢竟free是用在有memory allocate的情形的。萬一某個部分沒有寫好,比如我們的while如果沒有判斷rush != NULL,這時候會發生什麼事情也不曉得。即使free掉NULL沒什麼要緊的,但寫給自己看也讓自己提醒自己該注意的地方是什麼才是重要的。
沒有留言:
張貼留言