考研数据结构(每日一题)day23

考研数据结构(每日一题)

题目:设线性表L=(a1,a2,a3,…,an-2,an-1,an)采用带头结点的单链表保存,请设计一个空间复杂度为O(1)且时间上尽可能高效的算法,重新排列L中的各节点,得到线性表L’=(a1,an,a2,an-1,a3,an-2,…)

算法图解:

在这里插入图片描述

算法思想:

L’是由L取第一个元素,再取倒数第一个元素,以此类推,依次合并而成的。为了方便链表后半段取元素,需要先将L后半段原地逆置(如图红色方框部分),题目中要求空间复杂度为O(1),即不能用栈,否则每取最后一个结点都需要遍历一次链表。
算法详细步骤:
第一步:设置两个指针p、q,找出链表L的中间结点,指针p每次走一步,q每次走两步。当指针q到达链表尾部时,指针p刚好在链表的中间结点
第二步:将L的后半段结点原地逆置
第三步:从单链表前后两段中依次各取一个结点,按题目要求排列

完整代码:

typedef struct node{
    int data;
    struct node*next;
}NODE;
void Change_list(NODE *h){
    NODE *p,*q,*r,*s;     //初始化指针
    p = q = h;     //从头结点开始
    while(q -> next != NULL){     //寻找中间结点
        p = p -> next;    //p走一步
        q = q -> next;
        if(q -> next != NULL){
            q = q -> next;       //q走两步
        }
    }
    q = p -> next;      //p所指结点为中间结点,q为后半段链表的首结点
    p -> next = NULL;
    while(q != NULL){    //逆置链表后半段
        r = q -> next;
        q -> next = p -> next;
        p -> next = q;
        q = r;
    }
    s = h -> next;      //s指向前半段的第一个数据结点,也就是插入点
    q = p -> next;      //q指向后半段的第一个数据结点
    p -> next = NULL;
    while(q != NULL){    //将链表后半段的结点插入到指定位置
        r = q -> next;   //r指向后半段的下一个结点
        q -> next = s -> next;     //将q所指结点插入到s所指结点之后
        s -> next = q;
        s = q -> next;   //s指向前半段的下一个插入点
        q = r;
    }
}
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值