單鏈表的鏈式儲存只有一個指示後繼的指針域,因此,從某個結點出發只能順指針日後尋查其餘結點。若要尋查結點的直接前端,則須要從表頭指針出發。
爲了克服單鏈表的單向性缺點,在雙向鏈表的結點中有兩個指針域,一個指向直接後繼,一個指向直接前趨。前端
typedef struct double_list { int val; //結點的值 struct double_list* next; //後繼結點的指針域 struct double_list* pre;//前趨結點的指針域 }double_list;
首先malloc一個結點的空間,剛剛初始化的頭節點,其前指針與後指針都賦值爲空。node
void inite(double_list** head) { *head = (double_list*)malloc(sizeof(double_list)); (*head)->next = NULL; (*head)->pre = NULL; }
這裏有一個坑,爲何參數是二級指針?
由於結點中還有先後的指針域,因此若是傳遞一級指針,則出了函數做用域,先後指針仍是會返回默認的隨機地址。web
當新結點插入到鏈表當中時,與單鏈表操做相同,只不過多了一個前趨指針的指向,先將新結點的後指針指向後一個結點,前指針指向前一個結點,再將後結點的前指針指向新結點,前結點的後指針指向新結點,便可完成插入
svg
頭插法就是每當有新結點生成時,始終插入到頭節點後,頭插的實現相對簡單,可是頭插的順序與鏈表的輸出順序是相反的。
函數
void push_front(double_list* head,int val) { double_list* node = (double_list*)malloc(sizeof(double_list)); node->val = val; head->next->pre = node; node->next = head->next; head->next = node; node->pre = head; }
尾插法也就是先將指針遍歷到鏈表尾部,再從尾部插入新結點
spa
void push_back(double_list* head, int val) { double_list* phead = head; double_list* node = (double_list*)malloc(sizeof(double_list)); while (phead->next!= NULL) { phead = phead->next; } node->val = val; phead->next = node; node->next = NULL; node->pre = phead; }
結點的刪除相對簡單,只須要將要刪除的結點,前一個結點的後指針指向後一個結點,後一個結點的前指針指向前一個結點,再釋放掉該結點的內存便可。
3d
void erase(double_list* node) { node->next->pre = node->pre; node->pre->next = node->next; free(node); node = NULL; }
頭刪也就是每次都從頭節點的下一個結點刪除,每次刪除的都是鏈表中的第一個結點。指針
void pop_front(double_list* head) { double_list* temp = head->next; head->next->next->pre = head; head->next = head->next->next; free(temp); temp = NULL; }
尾刪也就是每次都遍歷到鏈表結尾出,每次刪除鏈表的最後一個結點。code
void pop_back(double_list* head) { double_list* phead = head; while (phead->next != NULL) { phead = phead->next; } phead->pre->next = NULL; free(phead); phead = NULL; }
double_list* find(double_list* head, int val) { double_list* phead = head; while (phead != NULL) { if (phead->val == val) return phead; phead = phead->next; } return NULL; }
遍歷整個鏈表,當找到與值相同的結點時,返回該結點xml
void print_list(double_list* head) { double_list* phead = head->next; while (phead->next != NULL) { printf("%d->", phead->val); phead = phead->next; } printf("%d", phead->val); }