#include<stdio.h>
#include<stdlib.h>
struct SLB
{
int data;
struct SLB *link,*rlink;
};
struct SLB *Create();
void Shu(struct SLB *head);
struct SLB *Change(struct SLB *head);
int main()
{
struct SLB *Shuang;
printf("请输入链表结点元素(输入-1回车结束输入):\n");
Shuang=Create();
printf("双链表创建结果如下:\n");
Shu(Shuang);
Shuang=Change(Shuang);
printf("交换结点顺序后链表元素排列如下:\n");
Shu(Shuang);
return 0;
}
struct SLB *Create() //创建双链表,我觉得跟单链表区别不太大
{
struct SLB *head=NULL,*p,*p1;
p=(struct SLB *)malloc(sizeof(struct SLB));
scanf("%d",&p->data );
p->link =NULL;
p->rlink =NULL;
while(p->data !=-1)
{
if(head==NULL)
{
head=p;
p1=p;
}
else
{
p1->rlink =p;
p->link =p1;
p1=p;
}
p=(struct SLB *)malloc(sizeof(struct SLB));
scanf("%d",&p->data );
p->link =NULL;
p->rlink =NULL;
}
return head;
}
void Shu(struct SLB *head)
{
struct SLB *p;
p=head;
while(p!=NULL)
{
printf("%-3d",p->data );
p=p->rlink ;
}
putchar('\n');
}
struct SLB *Change(struct SLB *head)
{
struct SLB *p,*L,*temp;
L=(struct SLB *)malloc(sizeof(struct SLB)); //这里我设置了头结点,这样交换头结点的时候也好返回
L->link =NULL;
L->rlink =head;
p=head;
int n;
printf("请输入要改变第几个结点的前后结点位置(大于1小于6):"); //这里要是严谨一点的话可以遍历看用户输入了多
//少结点,然后告诉用户要输入在这个范围内的数字,因为我们这题主要是交换,所以就不整
scanf("%d",&n);
int j=1;
while(j<n&&p!=NULL)
{
j++;
p=p->rlink ;
}
//链表结点交换类的题,不太熟悉的话多画图品一下,把它们的指针画一下该如何指,切记一定不要出现断开链表从而找不到它的前驱或者后驱结点
//比如有p1->p->p2,若你没有标记p2结点,但是你的p->next指向了别处或者为空,那么你就会出现找不到p2结点以及之后的链表了,也就是断开联系了,
//最好就是不要断开,如果不得已可以标志一下以防找不到,比如我下面的temp指针就是拿来标志的
//画图理解起来真的vividly,不然你可能觉得怎么指过去指过来脑子就晕了
//下面这几种指法我觉得可以合并,就是那种不一样的条件就区别一下,因为第一次交换双链表结点,我刚刚也看晕了,你们有空自己试试简化一下吧
if(n==2) //即交换第二个结点的前后结点,因为所需的它的前驱的前驱结点为空,所以分开讨论,可能也有更简单的,因为第一次写双链表可能不那么熟悉,可以自己去试试改改
{
L->rlink =p->rlink ;
p->rlink ->link =NULL;
p->link ->rlink =p->rlink ->rlink ;
p->rlink ->rlink ->link =p->link ;
p->rlink ->rlink =p;
p->link ->link =p;
temp=p->rlink ;
p->rlink =p->link ;
p->link =temp;
}
else if(n==5)//跟也是特殊结点,后驱的后驱结点位空
{
p->link ->link ->rlink =p->rlink ;
p->rlink ->link =p->link ->link ;
p->link ->rlink =NULL;
p->link ->link =p;
p->rlink ->rlink =p;
temp=p->rlink ;
p->rlink =p->link ;
p->link =temp;
}
else
{
p->link ->link ->rlink =p->rlink ; //画图会好理解一些
p->rlink ->link =p->link ->link ;
p->link ->rlink =p->rlink ->rlink ;
p->rlink ->rlink ->link =p->link ;
p->rlink ->rlink =p; //尤其下面这几个步骤,注意前后顺序!link一定是它的前驱结点,rlink是它的后继结点
p->link ->link =p;
temp=p->rlink ;
p->rlink =p->link ;
p->link =temp;
}
return L->rlink ;
}
已知 p 指向双向循环链表中的一个结点,其结点结构为 data、llink、rlink 三个域,写出算法 change(p),交换 p 所指向的结点和它的前缀结点的顺序(就是把p的前一个结点和后一个
于 2022-10-27 16:29:43 首次发布