严蔚敏数据结构 P39——算法2.20
两张强制递增双向循环链表(List和List2)按值的大小,递增归并于一张归并表(List3)(利用前置指针和后置指针进行正序输出)
/*
严蔚敏数据结构 P39——算法2.20
两张强制递增双向循环链表(List和List2)按值的大小,递增归并于一张归并表(List3)(利用前置指针和后置指针进行正序输出)
*/
//头文件
#include<stdio.h>
#include<stdlib.h>
//结构
typedef struct st //双向链表st的结构
{
int date; //数据域
struct st *TOP; //前置指针域
struct st *NEXT; //后置指针域
}list, *sqlist;
//函数区
int build_list(sqlist List) //建立双向链表_递增
{
int len, i, date;
sqlist NEW = NULL, temp = NULL; //NEW用于指向新开辟的结点,temp用于指向新开辟结点的前一个结点
sqlist t = NULL;
printf("输入需要开辟的元素个数:"); //提醒用户输入相对于的操作
scanf_s("%d", &len); //记录用户需要开辟的元素个数
temp = List; //将头指针的权限赋给temp
for (i = 1;i <= len;i++)
{
printf("请输入第%d个结点的元素(递增):", i); //提醒用户输入相对于的操作
scanf_s("%d", &date); //记录用户每次结点开辟的个数
NEW = (sqlist)malloc(sizeof(list)); //开辟新的结点并用NEW指向
if (!NEW)
{
printf("程序建立开辟结点有误,检查程序!\n"); //显示错误信息
exit(1); //退出程序
}
if (i >= 2) //当有了第一个元素,并输入了第二个元素
{
while (t->date > date) //比较是否大于第一个数,因为是递增
{
printf("输入有误,请重新输入第%d个结点的元素(递增):", i); //提醒用户输入相对于的操作
scanf_s("%d", &date); //记录用户每次结点开辟的个数
}
}
NEW->date = date; //将数据放进新结点的数据域
NEW->TOP = temp; //使新开辟结点的前置结点挂在前一个结点
temp->NEXT = NEW; //将新结点挂在前一个结点
temp = NEW; //将操作指针指向下一个结点
t = temp; //使t指向新结点的前一个结点
}
NEW->NEXT = List; //将尾结点的后置指针挂在头结点
List->TOP = NEW; //将头结点的前置指针指向尾结点
return len; //返回开辟个数
}
void prin(sqlist List) //遍历双向链表
{
sqlist p = NULL; //定义操作指针
p = List->NEXT; //将p指向第一个元素
printf("双向链表的值为:"); //显示信息
do
{
printf("%d ", p->date); //输出元素
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->date); //输出元素
p = p->TOP; //p指向上一个元素
} while (p != List); //如果p不为头结点(因为双向链表的尾结点指向头结点)
printf("\n");
}
int compute_len(int len1, int len2) //计算两个链表的和
{
int len3 = len1 + len2; //计算两个链表的长度和
return len3; //返回两个链表的长度和
}
void build_null(sqlist List3, int len) //建立空链表
{
int i;
sqlist NEW = NULL, temp = NULL; //NEW用于指向新开辟的结点,temp用于指向新开辟结点的前一个结点
temp = List3; //将头指针的权限赋给temp
for (i =