C 語言初學教材 - 第六章 刪除好友

刪除好友資料也就是在鏈結串列中刪掉某個節點,刪掉的概念很簡單,如下圖我們打算刪除打紅色叉叉的節點




然後將上一個節點的成員 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



結果如下



問題與討論
  1. 為什麼 delfriend() 也需要用到雙重指標當參數?
  2. 說明在鏈結串列中加入新節點及刪除舊節點的模式。




沒有留言: