然後將上一個節點的成員 nextPtr 指向所刪除節點的 nextPtr ,實際上就完成了刪除的工作,因為這樣一來,刪掉的節點便無法再參考,做法如下圖
為了使程式能做有效的記憶體管理,我們還需要呼叫標準函數庫中 stdlib.h 的函數 free() 來通知作業系統,程式不會再利用被刪除節點的記憶體空間,因此作業系統可以重新分配這些記憶體空間。注意,這並不代表原先儲存在節點的資料被抹去或消失,若是電腦記憶體仍足夠,作業系統並不需要配置多餘的記憶體空間,那麼儲存在這些記憶體位址的值,有可能在程式結束前都還存在。
以下為用來刪除好友資料的函數 delfriend() ,同樣需要雙重指標當參數
void delfriend(LinkedListNode **startPtr) { LinkedListNode *currentPtr, *previousPtr; char dname[NAME_SIZE]; int RESULT = N; printf("\n注意,這項功能會刪除好友資料....\n"); printf("請輸入所要刪除資料的好友暱稱: "); scanf("%s", dname); currentPtr = *startPtr; while (currentPtr != NULL) { if (!strcmp(currentPtr->data.name, dname)) { if (currentPtr == *startPtr) { *startPtr = currentPtr->nextPtr; } else { previousPtr->nextPtr = currentPtr->nextPtr; } free(currentPtr); RESULT = Y; break; } previousPtr = currentPtr; currentPtr = currentPtr->nextPtr; } if (RESULT == Y) { printf("\n好友資料刪除成功....\n"); } else { printf("\n無法刪除,沒有這名好友的資料喔!\n"); } }
由於可能需要修改 frienddata() 中的 startPtr 的值,也就是當刪除第一個節點時,要將 startPtr 指向第一個節點的成員 nextPtr ,所以需要用雙重指標當作參數。
取得好友暱稱後,便進入 while 迴圈以線性搜尋的方式找到要刪除的節點,由於這裡需要同時記錄兩個節點,所以並沒有套用線性搜尋的函數 lsearch() 。若是找到要刪除的好友資料,接著便先確認是否為第一個節點,用 if-else 做不同的處理,接著呼叫 free() 通知作業系統,該指標所指向的記憶體空間用不到了,然後設定狀態變數 RESULT 。最後跳出迴圈,依狀態變數印出提示訊息。
我們要在 itmf.c 加入這個函數定義,然後要在 itm.h 中加入函數原型的宣告
void delfriend(LinkedListNode **startPtr);
好了,來編譯執行看看吧!假設 david 已加入好友資料
輸入 2 ,開啟刪除好友的功能
刪除 david ,結果如下
再次輸入 2 ,刪除沒有加入好友資料的 bob
結果如下
問題與討論
- 為什麼 delfriend() 也需要用到雙重指標當參數?
- 說明在鏈結串列中加入新節點及刪除舊節點的模式。
沒有留言:
張貼留言