有了新增節點的類別方法,總該有一個刪除節點的類別方法吧!
刪除節點的方式有很多種,我們就從最簡單的刪除鏈結串列頭部節點開始。
class SLL {
private:
SLLNode *head;
public:
SLL();
void pushFront(int);
void printAll();
int popFront();
};
class DLL {
private:
DLLNode *head, *tail;
public:
DLL();
void pushFront(int);
void printAll();
int popFront();
};
從下面的程式碼可以看到,這個類別方法被分成 3 個情況來討論:
-1
head
設為 NULL
,並回傳該節點的內容head
向後移動,並回傳第一個節點的內容int SLL::popFront() {
if (this -> head == NULL)
return -1;
else if (this -> head -> next == NULL) {
int removeElement = this -> head -> data; // 先儲存到變數中,因為未來無法再觸及該節點
del this -> head; // 釋放動態記憶體
this -> head = NULL;
return removeElement;
}
else {
/*
head 指向的記憶體在未來會被釋放,
所以要先將這個節點的資料先取出,
否則未來無法再觸及該節點
*/
int removeElement = this -> head -> data;
SLLNode *temp = this -> head -> next;
del this -> head;
this -> head = temp;
return removeElement;
}
}
### 雙向鏈結串列
從下面的程式碼可以看到,這個類別方法被分成 3 個情況來討論:
1. 鏈結串列本身是空的:因為沒有資料內容,因此回傳 `-1`
2. 鏈結串列只有一個節點:刪除該節點後,要將 `head`, `tail` 設為 `NULL`,並回傳該節點的內容
3. 鏈結串列包含多個節點:將 `head` 向後移動,並回傳第一個節點的內容
int DLL::popFront() {
if (this -> head == NULL)
return -1;
else if (this -> head -> next == NULL) {
int removeElement = this -> head -> data; // 先儲存到變數中,因為未來無法再觸及該節點
del this -> head; // 釋放動態記憶體
this -> head = NULL;
this -> tail = NULL;
return removeElement;
}
else {
/*
head 指向的記憶體在未來會被釋放,
所以要先將這個節點的資料先取出,
否則未來無法再觸及該節點
*/
int removeElement = this -> head -> data;
DLLNode *temp = this -> head -> next;
del this -> head;
this -> head = temp;
return removeElement;
}
}
不知道你有沒有發現,過程中一直提到也許有節點在未來無法被觸及?
因為這個節點能被觸及,都是多虧了有指向他的指標,萬一這個指標被移動,我們將沒有任何途徑去接觸這個節點。
因此順序更顯得重要,否則會得到如 Runtime Error
, Segmentation Fault
等的錯誤訊息。
練習完了基本的增刪節點與動態記憶體配置,接下來我們要稍微加一點難度:學著在鏈結串列末端新增節點。