关于双向循环链表操作的一道题
【问题描述】输入n个整数,创建一个双向循环链表进行存储。这些整数从第二个开始,递增有序(设a2<a3<…<an) (ai为第i个整数)。试编写程序,创建双向循环链表,依次将输入的整数存储在该链表的各节点中。然后,将第一个结点删除并插入链表中的适当位置,使整个链表递增有序。
【输入形式】先输入整数的个数,再输入整数列。
【输出形式】以整数递增的顺序,依次输出双向循环链表各个节点存储的整数。
【样例输入】5 3 1 2 4 5
【样例输出】1 2 3 4 5
【样例说明】输入数据的第一个数是整数的个数,其后是整数列,该整数列从第二个开始,递增有序,数据间以空格分开。
【评分标准】根据输入的数据创建双向循环链表,并把原来部分有序的链表处理成有序的链表并输出。
博主开始数据结构的学习快一个月了。最近有这么一道题 ,一开始毫无思路,放到网上一搜竟然没有这道题的解析与类似的题目,这是我就思考了良久,最终看懂题目,并把它敲了出来并提交成功。中间几经坎坷,一直报运行时间过长的错误,然后看错误原因,原来是存在死循环。
我先直接上代码了。用的是C嗯上个学期学的是C++,没怎么学C,但是这个学期的数据结构主要是用C描述,也习惯了C的写法。
#include<stdio.h>
#include<stdlib.h>
typedef struct node* LinkList;
struct node{
int data;
LinkList next,pre;//双向循环链表必备的两个结构体指针
};
LinkList CreateLink(int n)
{
LinkList l;
l=(LinkList)malloc(sizeof(struct node));
l->next=l->pre=l;//因为创建头结点,所以只有一个结点故要自己与自己相连
LinkList p=l,q;
while(n--){
q=(LinkList)malloc(sizeof(struct node));
scanf("%d",&q->data);
p->next=q;
q->pre=p;
q->next=l;
l->pre=q;
p=q;
}
return l;
}//创建初始化一个循环链表的操作
LinkList merge(LinkList l)
{
LinkList p=l->next;
int m=p->data;
p->pre->next=p->next;
p->next->pre=p->pre;
free(p);//删除第一个元素
LinkList r=l->next;
while(r->data<m&&r->next!=l){
r=r->next;
}//通过比较遍历找到插入点 但要注意可能到最后都没找到比删除的元素还要大的结点 所以要再讨论是否到了尾结点
if(r->next!=l){
LinkList q;
q=(LinkList)malloc(sizeof(struct node));新建待插入的结点
q->data=m;//1
q->pre=r->pre;//2
q->next=r;//3
r->pre->next=q//;4
r->pre=q;//5重要的五步
}//在尾结点之前找到了比大的故插入进去
else{
LinkList q;
q=(LinkList)malloc(sizeof(struct node));
q->data=m;
r->next=q;
q->pre=r;
q->next=l;
l->pre=q;
}//遍历到了尾还没有找到大的元素
return l;
}
void show(LinkList l)//这就是简单的输出函数了
{
LinkList p=l->next;
while(p!=l)
{
printf("%d ",p->data);
p=p->next;
}
}
int main()//主函数
{
int n;
LinkList L,K;
scanf("%d",&n);
L=CreateLink(n);
K=merge(L);
show(K);
return 0;
}
代码还是比较简单 重点就是双向循环链表的创建要注意的一些问题比较繁琐 因为要来回指向 指向你
然后又指向回来 理清逻辑关系 把题目看懂了就可以轻松的敲出来了;
至于死循环的错误就是不小心把双向链表想成了单向链表以为尾结点->next=NULL其实是头结点哎
这个过于粗心
程序员就是这样啊哈哈哈哈哈
就这样吧有问题可以评论哦