通过只调用指针(不是数据)来完成两个相邻元素的交换。1.单链表操作 2.双链表操作

#include<stdio.h>
#include<stdlib.h>

struct Lian *CreateD();   //单链表创建
struct LianS *CreateS();   //双单链表创建
void Print(struct Lian *head,struct LianS *head1);//链表输出
struct Lian *SwapD(struct Lian *head);//单链表结点交换
struct LianS *SwapS(struct LianS *head);//双链表结点交换

struct Lian //单链表结构体
{
    int data;
    struct Lian *next;
};

struct LianS //双链表结构体
{    int data;
    struct LianS *light,*right;
};

int main()
{
    struct Lian *L;
    struct LianS *P;
    L=CreateD();  //单链表创建
    P=CreateS();  //双链表创建
    Print(L,P);  //链表输出,验证是否创建成功

    L=SwapD(L);  //单链表结点交换
    P=SwapS(P);  //双链表结点交换

    Print(L,P);  //链表输出,验证是否交换成功

    return 0;
}

struct Lian *CreateD()  //单链表创建
{
    struct Lian *head=NULL,*p,*p1;
    p=(struct Lian *)malloc(sizeof(struct Lian));
    scanf("%d",&p->data );
    p->next =NULL;
    while(p->data !=-1)
    {
        if(head==NULL)
        {
            head=p;
            p1=p;
        }
        else
        {
            p1->next =p;
            p1=p;
        }
        p=(struct Lian *)malloc(sizeof(struct Lian));
        scanf("%d",&p->data );
        p->next =NULL;
    }
    return head;
}

struct LianS *CreateS()  //双链表创建
{
    struct LianS *head=NULL,*p,*p1;
    p=(struct LianS *)malloc(sizeof(struct LianS));
    scanf("%d",&p->data );
    p->light =NULL;
    p->right =NULL;
    while(p->data !=-1)
    {
        if(head==NULL)
        {
            head=p;
            p1=p;
        }
        else
        {
            p1->right =p;
            p->light =p1;
            p1=p;
        }
        p=(struct LianS *)malloc(sizeof(struct LianS));
        scanf("%d",&p->data );
        p->light =NULL;
        p->right =NULL;
    }
    return head;
}

void Print(struct Lian *head,struct LianS *head1)    //链表输出
{
    struct Lian *p;
    struct LianS *l;
    p=head;
    l=head1;
    while(p!=NULL)
    {
        printf("%3d",p->data );
        p=p->next ;
    }
    putchar('\n');
    while(l!=NULL)
    {
        printf("%3d",l->data );
        l=l->right ;
    }
    putchar('\n');
}

struct Lian *SwapD(struct Lian *head)  //单链表结点交换
{
    struct Lian *p,*p1;
    p=(struct Lian *)malloc(sizeof(struct Lian));
    p->next =head;  //设置头结点,方便头结点进行交换的情况
    p1=head;
    int x,y,i;
    printf("请输入要交换哪两个结点:");
    scanf("%d %d",&x,&y);
    for(i=1;i<x;i++)
    {
        p=p->next ;
        p1=p1->next ;
    }
    if(p1==NULL||p1->next ==NULL)  //表示要交换的结点位置超过链表结点位置范围,就重新输入
    {
        printf("结点位数输入过长,请重新输入!\n");
        SwapD(head);   //重新调用结点交换函数
        return head;
    }
    else 
    {
        p->next =p1->next ; //最好画图理解,注意指针不能断开
        p1->next =p1->next ->next ;
        p->next ->next =p1;
        if(x==1)  //表示交换了第一个结点
           return p->next ;
        else
           return head;
    }
}

struct LianS *SwapS(struct LianS *head)  //双链表结点交换
{
    struct LianS *p,*p1;
    p=(struct LianS *)malloc(sizeof(struct LianS));
    p->light =NULL;
    p->right =head;
    p1=head;
    int x,y,i;
    printf("请输入要交换哪两个结点:");
    scanf("%d %d",&x,&y);
    for(i=1;i<x;i++)
    {
        p=p->right ;
        p1=p1->right ;
    }
    if(p1==NULL||p1->right ==NULL)  //表示要交换的结点位置超过链表结点位置范围,就重新输入
    {
        printf("结点位数输入过长,请重新输入!\n");
        SwapS(head);
        return head;
    }
    else   //多画图,双链表交换这有点绕
    {
        struct LianS *temp;  //为了使操作相对容易一点,可以设置一个中间结点
        temp=(struct LianS *)malloc(sizeof(struct LianS));
        temp=p1->right ;
        p->right =temp;
        temp->light =p;
        p1->light =temp;
        if(temp->right ==NULL)   //因为双链表要考虑左指针的指向问题,若交换最后两个结点时,最后一个结点后为NULL,因此无左指针,所以分情况讨论
        {
            p1->right =NULL;
            temp->right =p1;
        }
        else
        {
            p1->right =temp->right ;
            temp->right ->light =p1;
            temp->right =p1;
        }
        if(x==1)
           return p->right  ;
        else
           return head;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值