
比单线链表多一个上一个地址点相比于单向链表增加一个指针域保存前驱结点的地址方便向前或者向后索引。API1.创建双向链表2. 链表结点插入3. 链表结点删除4. 链表结点的查找5. 链表结点的修改6. 遍历7. 链表销毁查找和修改比较简单大家可以自行进行摸索下面我将展示一下其他的操作过程1.创建双向链表创建链表之初我们要进行构造结构体 这个需要我们放在我们的点h文件之中以方便在我们之后去调用1.要先定义节点再去定义主要链表双向链表可以双向移动typedef struct stu { char name[32]; int age; int score; }Data_t; //链表结点类型 typedef struct dnode { Data_t data; //结点数据域 struct dnode *ppre; //结点指针域指向前驱结点 struct dnode *pnext; //结点指针域指向后继结点 }DNode_t; //双向链表对象类型 typedef struct dlink { DNode_t *phead; //指向头节点的指针 int clen; //当前结点个数 }DLink_t;这一段便是在c文件中去进行初始化调用实现Dlink_t *create_doulink() { Dlink_t *dplink malloc(sizeof(Dlink_t)); if(NULLdplink) { printf(error\n); return NULL; } dplink-pheadNULL; dplink-clear0; return dplink; }2. 链表结点插入在链表插入的时候需要判定是否为空如果不为空可能插入方式会有所变化int is_empty_link(Dlink_t *dplink) { return NULL dplink-phead; } int insert_doulink_head(Dlink_t * dplink,Date_t data) { DNode_t * pinsert malloc(sizeof(DNode_t)); if(NULLpinsert) { printf(error\n); return -1; } pinsert-data data;//定义好带插入点的初始化 pinsert-ppre NULL; pinsert-pnext NULL; if(is_empty_link(dplink)) { dplink-pheadpinsert; } else { pinsert-pnextdplink-phead; //进行头插 dplink-phead-pprepinsert; dplink-pheadpinsert; } dplink-clear; return 0; }那我们还需要掌握的是尾部插入可以对照头插进行理解。int insert_doulink_tail(Dlink_t *dplink,Date_t date) { DNode_t * pinsert malloc(sizeof(DNode_t)); if(NULLpinsert) { printf(error\n); return -1; } pinsert-data date; pinsert-ppre NULL; pinsert-pnext NULL; if(is_empty_link(dplink)) { dplink-phead pinsert; } else { DNode_t *tmp dplink-phead; while(tmp-pnext!NULL) { tmptmp-pnext; } tmp-pnext pinsert; pinsert-ppre tmp; dplink-clear; } return 0; }3. 链表结点删除双向链表的头部删除和尾部删除以内双向链表有pre地址指向前一个地址点所以在删除的时候需要进行遍历void del_tail(Dlink_t *dplink) { if(is_empty_link(dplink)) { printf(error); return ; } DNode_t *pfree dplink-phead; if(dplink-phead-pnextNULL) { free(pfree); dplink-pheadNULL; } else { while(pfree-pnext!NULL) { pfreepfree-pnext; } pfree-ppre-pnextNULL; free(pfree); pfreeNULL; dplink-clear--; } } void del_head(Dlink_t *dplink) { DNode_t *pfree dplink-phead; if(dplink-clear0) { return ; } else if(dplink-clear1) { dplink-pheadNULL; } else if(pfree!NULL) { dplink-phead pfree-pnext; pfree-pnext-ppre NULL; } dplink-clear--; free(pfree); }4. 链表销毁我们直接调用头删进行遍历就好了最后记得把dplink链表进行free防止数据溢出void destory_link(Dlink_t *dplink) { while(!is_empty_link(dplink)) { del_head(dplink); } free(dplink); }