1. 程式人生 > >循環雙向鏈表的

循環雙向鏈表的

結構體 定位 all tail 判斷 循環鏈表 結點 初級 雙向鏈表

鏈表的使用

初級版:

  結構體

  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去創建,內核中的雙向鏈表正是這麽實現的,

  特別容易書寫,不太會產生副作用。二級指向是在太難理解了

循環雙向鏈表的