情况有三:
- 情况1:删除链表的第一个结点
(1) 将指向链表开始的指针head指向第二个结点.
(2) 此时原链表的第二个结点将成为新链表的开始,并且将新链表开始结点的指针back设为NULL.
- 情况2:删除最后一个结点
将原链表的最后一个结点之前一个结点的指针from设为NULL.
- 情况3:删除链表内中间结点
(1) 将链表内指针ptr所指结点的前一个结点指针front指向指针ptr所指结点的下一个结点.
(2) 将链表内指针ptr所指结点的最后一个指针back指向指针ptr所指结点的前一个结点.
双向链表内结点删除
#include " iostream " #include " stdlib.h " using namespace std; struct dlist // 双向链表结构声明 { int data; // 结点数据 struct dlist * front; // 指向下一结点的指针 struct dlist * back; // 指向前一结点的指针 };typedef struct dlist dnode; // 双向链表新类型 typedef dnode * dlink; // 双向链表指针新类型 /* -----使用数组值创建双向链表---- */ dlink createdlist( int * array, int len){ dlink head; // 双向链表的指针 dlink before; // 前一节点的指针 dlink new_node; // 新结点的指针 int i; /* ------创建第一个结点-------- */ /* --------分配结点内存-------- */ head = (dlink)malloc( sizeof (dnode)); if ( ! head) // 检查内存指针 return NULL; head -> data = array[ 0 ]; // 创建结点内容 head -> front = NULL; // 设置指针初值 head -> back = NULL; // 设置指针初值 before = head; // 指向第一个结点 for (i = 1 ;i < len;i ++ ) // 用循环创建其他结点 { /* --分配结点内存-- */ new_node = (dlink)malloc( sizeof (dnode)); if ( ! new_node) return NULL; new_node -> data = array[i]; // 创建结点内容 new_node -> front = NULL; new_node -> back = before; // 将新结点指向前结点 before -> front = new_node; // 新结点成为前结点 before = new_node; } return head;} /* --------释放双向链表的内存----------- */ void freedlist( dlink head){ dlink ptr; // 存储目前结点指针 while (head != NULL) // 链表遍历循环 { ptr = head; // 保留目前结点指针 head = head -> front; // 指向下一个结点 free(ptr); // 释放目前结点内存 }} /* -------双向链表的输出-------- */ void printdlist( dlink head,dlink now){ while (head != NULL) // 链表遍历循环 { if (head == now) // 输出目前结点数据 printf( " #%d# " ,head -> data); // 输出结点数据 else printf( " [%d] " ,head -> data); // 输出结点数据 head = head -> front; // 指向下一个结点 } printf( " \n " );} /* -------双向链表的结点删除-------- */ dlink deletenode(dlink head,dlink ptr){ if (ptr -> back == NULL) // 是否有前结点 { /* ----情况1:删除第一个结点---- */ head = head -> front; // 指向下一个结点 head -> back = NULL; // 设置指向前结点的指针 } else { if (ptr -> front == NULL) // 是否指向下一个结点 { /* ---情况2:删除最后一个结点--- */ ptr -> back -> front = NULL; // 前结点指向NULL } else { /* ----情况3:删除中间结点---- */ ptr -> back -> front = ptr -> front; // 前结点指向下一结点 ptr -> front -> back = ptr -> back; // 下一结点指向前结点 } } free(ptr); // 释放删除结点内存 return head; // 返回链表起始指针 } /* -------------使用选项来移动结点后,删除目前的结点且将列出链表内容-------------- */ int main(){ dlink head ; // 双向链表指针 dlink now = NULL; // 目前结点指针 int list[ 6 ] = { 1 , 2 , 3 , 4 , 5 , 6 }; int select; // 选择项1~4 head = createdlist(list, 6 ); if (head == NULL) { printf( " 内存分配失败!n " ); exit( 1 ); } while ( 1 ) { if (now == NULL) now = head; // 目前指向第一结点 printf( " 链表内容是: " ); printdlist(head,now); /* ---选项内容--- */ printf( " [1]往下移动 [2]往回移动 [3]删除结点 [4]离开 ==> " ); scanf( " %d " , & select); switch (select) { /* ---往下移动-- */ case 1 : if (now -> front != NULL) now = now -> front; // 指向下一结点 else printf( " 在链表结尾\n " ); break ; /* ----往回移动---- */ case 2 : if (now -> back != NULL) now = now -> back; // 指向前一结点 else printf( " 在链表开始\n " ); break ; /* ----删除目前结点---- */ case 3 : if (head != NULL) { head = deletenode(head,now); now = head; // 目前指向第一结点 } else printf( " 链表是空的\n " ); break ; /* ----------离开--------- */ case 4 : freedlist(head); exit( 1 ); } } }