循環雙向鏈表的
鏈表的使用
初級版:
結構體
struct data{
struct data* next;
int data;
};
head=p1->p2->p3->p4->NULL
需要刪除節點p3時就很麻煩,我們需要從頭去遍歷,找到next指針為p3時將next指針指向p3的next;
為此方便起見,我們可以使用雙向鏈表進行實現。操作會簡單許多
NULL<-head=>p1<=>p2<=>p3<=>p4->NULL;
刪除p3節點時,我們需要獲取p2(p3->pre)
p3->pre->next = p3->next;
p3->next->pre = p3->pre;
這時我們需要判斷p3->pre p3->next是否存在,不存在時直接段錯誤。
內核中是這樣處理的,
創建一個雙向循環鏈表
=>head<=>p1<=>p2<=>p3<=>p4=
向鏈表中指定位置插入節點
原有鏈pre<=>next
這也是最基本的插入節點的方法
_add_data(struct data* input,struct data* pre,struct data* next){
pre->next = input;
input->pre = pre;
next->pre = input;
input->next = next;
}
頭插法在_add_data的基礎上實現就直觀多了;
add_head(struct data *input,struct data* head){
_add_data(input,head,head->next);//在頭和頭的下一個節點插入節點
}
尾插法
add_tail(struct data *input,struct data * head){
_add_data(input,head->pre,head);//頭節點的前一個節點就是尾,在尾和頭結點之間插入就是插入到尾了。
}
根據插入節點的方式寫刪除節點就容易的多了
_del(struct data * pre,struct data * next){
pre->next = next;
next->pre = pre;
}
del(struct data* input){
_del(input->pre,input->next);//執行完後,節點就從鏈上摘下來了。
}
沒有做釋放的代碼,創建鏈的時候需要用malloc去創建,內核中的雙向鏈表正是這麽實現的,
特別容易書寫,不太會產生副作用。二級指向是在太難理解了
循環雙向鏈表的