严蔚敏数据结构 P36页——双向链表的插入
/*
严蔚敏数据结构 P36页——双向链表的插入
*/
//头文件
#include<stdio.h>
#include<stdlib.h>
//结构
typedef struct st
{
int data; //数据域
struct st *TOP; //前置指针
struct st *NEXT; //后置指针
}list, *sqlist;
//函数区
void set_list(sqlist LIST) //建立双向链表
{
int date, len, i;
sqlist NEW = NULL, TEMP = NULL; //NEW用于指向新开辟的结点,TEMP用于指向新结点的前一个结点
printf("请输入需要开辟的结点个数:"); //显示提醒用户相对应的操作
scanf_s("%d", &len); //利用date记录长度数据
TEMP = LIST; //将TEMP指向头结点的下一个结点
for (i = 1;i <= len;i++) //开辟各个结点
{
printf("请输入第%d个结点的数据:", i); //显示提醒用户输入相对应的操作
scanf_s("%d", &date); //记录输入
NEW = (sqlist)malloc(sizeof(list)); //建立新结点
if (!NEW) //判断是否开辟成功
{
printf("程序建立开辟结点有误,检查程序!\n"); //显示错误信息
exit(1); //退出程序
}
NEW->data = date; //将用户输入的数据写进新结点的数据域里面
NEW->NEXT = NULL; //将新开辟结点的后置指针挂起
TEMP->NEXT = NEW; //将新结点的前一个结点指向新结点
NEW->TOP = TEMP; //将NEW的前置结点指向上一个结点,构成双向链表
TEMP = TEMP->NEXT; //将移动指针向下一个结点移动
}
NEW->NEXT = LIST; //将尾结点的后置指针指向头结点
LIST->TOP = NEW; //将头结点的前置指针指向尾结点
}
void prin(sqlist List) //遍历双向链表
{
sqlist p = NULL; //定义操作指针
p = List->NEXT; //将p指向第一个元素
printf("双向链表的值为:"); //显示信息
do
{
printf("%d ", p->data); //输出元素
p = p->NEXT; //p指向下一个元素
} while (p != List); //如果p不为头结点(因为双向链表的尾结点指向头结点)
printf("\n");
}
void against_prin(sqlist List) //遍历双向链表(尾结点遍历)(用于判断双向链表)
{
sqlist p = NULL; //定义操作指针
p = List->TOP; //将p指向第一个元素
printf("双向链表逆序的值为:"); //显示信息
do
{
printf("%d ", p->data); //输出元素
p = p->TOP; //p指向上一个元素
} while (p != List); //如果p不为头结点(因为双向链表的尾结点指向头结点)
printf("\n");
}
void insert_list(sqlist LIST) //插入操作
{
int date, len, i;
sqlist NEW = NULL, TEMP = NULL, s = NULL; //NEW用于指向新开辟的结点,TEMP用于指向新结点的前一个结点
printf("输入你要插入结点的位置:"); //显示提醒用户输入相对应的操作
scanf_s("%d", &len); //记录操作
printf("输入你要插入结点的数据:"); //显示提醒用户相对应的操作
scanf_s("%d", &date); //记录操作
NEW = (sqlist)malloc(sizeof(list)); //开辟新结点
if (!NEW) //判断是否开辟成功
{
printf("程序建立开辟结点有误,检查程序!\n"); //显示错误信息
exit(1); //退出程序
}
NEW->NEXT = NULL; //新结点的后置指点挂起
NEW->TOP = NULL; //新结点的前置指针挂起
TEMP = LIST; //将头指针权限赋给TEMP
for (i = 1;i < len;i++) //指向指到需要插入位置的前一个位置
{
TEMP = TEMP->NEXT; //移动指向下一个结点
}
s = TEMP->NEXT; //将插入元素的下一个下一个结点用s指向
NEW->data = date; //将数据赋给NEW的指针域
TEMP->NEXT = NEW; //将插入位置的上一个结点指向新结点
NEW->NEXT = s; //将新结点的后置结点指向插入位置的结点
s->TOP = NEW; //将s的前置指针指向新结点
NEW->TOP = TEMP; //将新结点的前置指针指向新结点的上一个结点
}
//主函数
int main(void)
{
sqlist LIST = NULL; //定义头指针
LIST = (sqlist)malloc(sizeof(list)); //开辟头结点
if (!LIST)
{
printf("程序建立开辟结点有误,检查程序!\n"); //显示错误信息
exit(1); //退出程序
}
LIST->NEXT = NULL; //将头结点的后置指针挂起
LIST->TOP = NULL; //将头结点的前置指针挂起
set_list(LIST); //建立双向链表
prin(LIST); //正序输出
against_prin(LIST); //逆序输出
insert_list(LIST); //插入操作
prin(LIST); //正序输出
against_prin(LIST); //逆序输出
return 0;
}
双向链表的结构:
建立一个名为st的双向链表结构体名,list表示st双向循环链表的结构体,sqlist表示st结构体的指针
//结构
typedef struct st
{
int data; //数据域
struct st *TOP; //前置指针
struct st *NEXT; //后置指针
}list, *sqlist;
建立双向链表:
//函数区
void set_list(sqlist LIST) //建立双向链表
{
int date, len, i;
sqlist NEW = NULL, TEMP = NULL; //NEW用于指向新开辟的结点,TEMP用于指向新结点的前一个结点
printf("请输入需要开辟的结点个数:"); //显示提醒用户相对应的操作
scanf_s("%d", &len); //利用date记录长度数据
TEMP = LIST; //将TEMP指向头结点的下一个结点
for (i = 1;i <= len;i++) //开辟各个结点
{
printf("请输入第%d个结点的数据:", i); //显示提醒用户输入相对应的操作
scanf_s("%d", &date); //记录输入
NEW = (sqlist)malloc(sizeof(list)); //建立新结点
if (!NEW) //判断是否开辟成功
{
printf("程序建立开辟结点有误,检查程序!\n"); //显示错误信息
exit(1); //退出程序
}
NEW->data = date; //将用户输入的数据写进新结点的数据域里面
NEW->NEXT = NULL; //将新开辟结点的后置指针挂起
TEMP->NEXT = NEW; //将新结点的前一个结点指向新结点
NEW->TOP = TEMP; //将NEW的前置结点指向上一个结点,构成双向链表
TEMP = TEMP->NEXT; //将移动指针向下一个结点移动
}
NEW->NEXT = LIST; //将尾结点的后置指针指向头结点
LIST->TOP = NEW; //将头结点的前置指针指向尾结点
}
正序输出双向链表:
void prin(sqlist List) //遍历双向链表
{
sqlist p = NULL; //定义操作指针
p = List->NEXT; //将p指向第一个元素
printf("双向链表的值为:"); //显示信息
do
{
printf("%d ", p->data); //输出元素
p = p->NEXT; //p指向下一个元素
} while (p != List); //如果p不为头结点(因为双向链表的尾结点指向头结点)
printf("\n");
}
逆序输出双向链表:
void against_prin(sqlist List) //遍历双向链表(尾结点遍历)(用于判断双向链表)
{
sqlist p = NULL; //定义操作指针
p = List->TOP; //将p指向第一个元素
printf("双向链表逆序的值为:"); //显示信息
do
{
printf("%d ", p->data); //输出元素
p = p->TOP; //p指向上一个元素
} while (p != List); //如果p不为头结点(因为双向链表的尾结点指向头结点)
printf("\n");
}
本程序核心操作(插入):
void insert_list(sqlist LIST) //插入操作
{
int date, len, i;
sqlist NEW = NULL, TEMP = NULL, s = NULL; //NEW用于指向新开辟的结点,TEMP用于指向新结点的前一个结点
printf("输入你要插入结点的位置:"); //显示提醒用户输入相对应的操作
scanf_s("%d", &len); //记录操作
printf("输入你要插入结点的数据:"); //显示提醒用户相对应的操作
scanf_s("%d", &date); //记录操作
NEW = (sqlist)malloc(sizeof(list)); //开辟新结点
if (!NEW) //判断是否开辟成功
{
printf("程序建立开辟结点有误,检查程序!\n"); //显示错误信息
exit(1); //退出程序
}
NEW->NEXT = NULL; //新结点的后置指点挂起
NEW->TOP = NULL; //新结点的前置指针挂起
TEMP = LIST; //将头指针权限赋给TEMP
for (i = 1;i < len;i++) //指向指到需要插入位置的前一个位置
{
TEMP = TEMP->NEXT; //移动指向下一个结点
}
s = TEMP->NEXT; //将插入元素的下一个下一个结点用s指向
NEW->data = date; //将数据赋给NEW的指针域
TEMP->NEXT = NEW; //将插入位置的上一个结点指向新结点
NEW->NEXT = s; //将新结点的后置结点指向插入位置的结点
s->TOP = NEW; //将s的前置指针指向新结点
NEW->TOP = TEMP; //将新结点的前置指针指向新结点的上一个结点
}
讲解:
通过for循环将TEMP指针指向,需要插入位置的上一个结点
for (i = 1;i < len;i++) //指向指到需要插入位置的前一个位置
{
TEMP = TEMP->NEXT; //移动指向下一个结点
}
在利用s指针指向,需要插入位置的结点
s = TEMP->NEXT; //将插入元素的下一个下一个结点用s指向
最后进行,插入的操作:
NEW->data = date; //将数据赋给NEW的指针域
TEMP->NEXT = NEW; //将插入位置的上一个结点指向新结点
NEW->NEXT = s; //将新结点的后置结点指向插入位置的结点
s->TOP = NEW; //将s的前置指针指向新结点
NEW->TOP = TEMP; //将新结点的前置指针指向新结点的上一个结点
感谢观看
再次感谢~