情况有三:
- 情况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 );
}
}
}
#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 );
}
}
}