数组+链表 小球移动过程

              
    假设有一系列的小球为1~n,顺序可以不按照规则的数字排列,要求输出2个数字,n和m(分别对应小球中的顺序),如果n<m,则让n跑到m的前面去,如果n>m,则让m跑到n的后边去,依然保持原来的整体结构不变。

    这个题目就是一个典型的用线性结构来计算的题目,我们可以用两种方式来实现,数组和链表都可以很好的解决为题,这里我采用了单链表来解决,双向链表也可以解决该问题

    用数组来实现的代码如下:
# include <stdio.h>
int arr[100];

int find(int n);
void unshift_left(int n,int m);
void unshift_right(int n,int m);
void traverse(void);

int main(void){
    int i;
    int n,m,left,right;
    for(i=1;i<=50;i++){
        arr[i] = i;  //初始化小球的排列顺序,可以不按照固定的顺序
    }
    
    scanf("%d%d",&n,&m);
    left = find(n);  //找到第一个小球对应的值
    right = find(m);  //找到第二个小球对应的值
    if(left>right)
        unshift_right(right,left); //排列小球的顺序
    else
        unshift_left(left,right);  //排列小球的顺序
    traverse();
    return 0;
}


int find(int n){
    int i;
    int count = 1;
    for(i=1;i<=50;i++){
        if(arr[i] == n){
            return count;
        }else{
            count++;
        }
    }    
}

void traverse(void){
    int i;
    for(i=1;i<50;i++){
        printf("%d ",arr[i]);
    }
}

void unshift_left(int n,int m){
    int i;
    int num = arr[n];
    for(i=n;i<m-1;i++){
        arr[i] = arr[i+1];
    }
    arr[m-1] = num;
}


void unshift_right(int n,int m){
    int i;
    int num = arr[m];
    for(i=m;i>n+1;i--){
        arr[i] = arr[i-1];
    }
    arr[n+1] = num;
}



    链表的实现方式如下:

# include <stdio.h>
# include <malloc.h>

typedef struct NODE{
    int data;
    struct NODE *pNext;
}NODE,*PNODE;


PNODE create_list();
void traverse(PNODE pHead);    
void unshift_left(PNODE pHead,int n,int m);

int main(void){
    int n,m;
    PNODE pHead = NULL;
    pHead = create_list();    //创建一个链表
    scanf("%d%d",&n,&m);
    unshift_left(pHead,n,m);  //排列小球的顺序
    traverse(pHead);
    return 0;
}

PNODE create_list(){
    int i;
    PNODE pHead = (PNODE)malloc(sizeof(NODE));
    pHead->pNext = NULL;
    PNODE pTail = pHead;
    for(i=1;i<50;i++){
        PNODE pNew = (PNODE)malloc(sizeof(NODE));
        pNew->data = i;
        pNew->pNext = NULL;
        pTail->pNext = pNew;
        pTail = pNew;
    }
    return pHead;
}

void traverse(PNODE pHead){
    PNODE p = pHead;
    while(p->pNext != NULL){
        printf("%d ",p->pNext->data);
        p = p->pNext;
    }
}    

void unshift_left(PNODE pHead,int n,int m){
    PNODE p = pHead;
    PNODE p1=NULL,p2=NULL;
    int count=0;
    while(p->pNext !=NULL){
        count++;
        if(n < m){
            if(count == n){
                p1 = p->pNext;    
                p->pNext = p->pNext->pNext;
                count++; //这里count++的原因是上面p->pNext的值多移动了一位
            }
            if(count == m){
                PNODE p2 = p->pNext;
                p->pNext = p1;
                p1->pNext = p2;
            }
        }else{
        
            if(count == m){
                p1 = p->pNext;
                p2 = p->pNext->pNext;
            }
            if(count == n){
                PNODE p3 = p->pNext;    
                p->pNext = p->pNext->pNext;
                p1->pNext = p3;
                p3->pNext = p2;
            }
            
        }
        p = p->pNext;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值