循环双链表的一个应用和与数组的比较

链表是数据结构中常见的一种,使用也很频繁 。但大多时候可以使用链表则也可以使用数组 下面在一个例子中分别使用数组和链表来对比下两者的区别和各自的特点.
题目:小球 从左到右一次编号为 1,2,3,4,5…n 可以执行两种指令 A x y 或者B x y
A x y 为将x 编号的球放到y编号的球的左边
B x y 为将x编号的球放到y编号的球的右边
最后输出整个球的经过调整后的顺序
输入:6 2
A 2 4
B 3 6
输出:1 2 4 5 6 3
输入:6 为球的个数 2 为操作的次数
A 2 4 和B 3 6为两次操作 分别将2放到4的左边 3 放到6的右边
输出 为最后的球的顺序.
下面我将用数组和循环双链表来模拟这种操作

下面是使用数组来模拟的代码

#include <stdio.h>
#include <stdlib.h>
int find(int* data,int x,int n)//在data数组里找到x 并返回他的下标
{
    int i=1;
    for(;i<=n;i++)
        if(data[i]==x)
        return i;
}
void shift_right(int start,int end,int *data)//在data数组里从start开始到end结束全部向右边移动一位
{
    int i=end;
    for(;i>=start;i--)
        data[i+1]=data[i];

}
void shift_left(int start,int end,int *data)//在data数组里从start开始到end结束全部向左边移动一位
{
    int i=start;
    for(;i<=end;i++)
        data[i-1]=data[i];
}
int main()
{
    int n,m,i;
    int *data;
    scanf("%d%d",&n,&m);//n为球的个数 m为操作的次数
    data=(int *)malloc((n+1)*sizeof(int));//申请内存空间
    for(i=1;i<=n;i++)//模拟n个小球的情况
        data[i]=i;
    for(i=1;i<=m;i++)
    {
        char type[10];
        int x,y,p,q,temp;
        scanf("%s%d%d",type,&x,&y);//输入移动类型和两个小球的数字
        p=find(data,x,n);
        q=find(data,y,n);
        if(type[0]=='A')//将x放在y左边
        {
            if(p>q)
            {
                temp=data[p];
                shift_right(q,p-1,data);//移动数组
                data[q]=temp;
            }
            else
            {
                temp=data[p];
                shift_left(p+1,q-1,data);//移动数组
                data[q-1]=temp;

            }
        }
        else//将x放在y右边
        {
            if(p>q)
            {
                temp=data[p];
                shift_right(q+1,p-1,data);//移动数组
                data[q+1]=temp;
            }
            else
            {
                temp=data[p];
                shift_left(p+1,q,data);//移动数组
                data[q]=temp;
            }
        }
    }
    for(i=1;i<=n;i++)
        printf("%d ",data[i]);
}

下面是使用循环双链表来模拟的代码

#include <stdio.h>
#include <stdlib.h>
typedef struct linknode{
    struct linknode *left;
    struct linknode *right;
    int data;

}LinkNode;
void Link(LinkNode *x,LinkNode *y)//将y放到x 的右边
{
    x->right=y;
    y->left=x;
}
LinkNode *Find(int x,LinkNode *p)
{
    while(p->data!=x)
        p=p->right;
    return p;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    LinkNode*p=(LinkNode*)malloc(sizeof(LinkNode));
    int i=1;
    LinkNode *pre=p,*now;//前驱指针初始化
    p->data=0;
    for(;i<=n;i++)//创建链表
    {
        now=(LinkNode*)malloc(sizeof(LinkNode));
        now->data=i;
        Link(pre,now);
        pre=now;
    }
    Link(now,p);//形成环型双链表
    char type[10];
    int x,y;
    for(i=1;i<=m;i++)
    {
        scanf("%s%d%d",type,&x,&y);
        LinkNode *xpointer,*ypointer;
        xpointer=Find(x,p);//找到x
        ypointer=Find(y,p);//找到y
        xpointer->left->right=xpointer->right;
        xpointer->right->left=xpointer->left;//删除x
        if(type[0]=='A')//x在y的左边
        {
            Link(ypointer->left,xpointer);
            Link(xpointer,ypointer);
        }
        else//x在y的右边
        {
            Link(xpointer,ypointer->right);
            Link(ypointer,xpointer);
        }
    }
    now=p->right;
    while(now!=p)
    {
        printf("%d ",now->data);
        now=now->right;
    }


}

下面来分析下两者的区别和各自的优点
利用数组来模拟的话则需要不停的来移动数组的元素 例如6个球 编号为1 2 3 4 5 6如果我要将2放在6的右边则我必须
把3 4 5 6都向左边移动一位然后再将2插到6原来的位子上 利:实现简单 弊:如果元素过多则会有很多的元素移动会大大降低运行速度
利用链表来模拟上次的这个过程的话则要先将2从循环双链表中删除然后再将其插入6的右边 。利:代码的执行速度会大大的提高 弊 :实现可能比用数组的话复杂了一点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hebastast

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值