王道c语言-链表分为两半,逆置后一半,与前一半轮流合并

王道c语言-链表分为两半,逆置后一半,与前一半轮流合并

设线性表 L = ( a 1 , a 2 , a 3 , ⋯   , a n − 2 , a n − 1 , a n ) L=(a_1,a2,a3,\cdots,a_{n-2},a_{n-1},a_{n}) L=(a1,a2,a3,⋯,an−2,an−1,an) 采用带头结点的单链表保存,设计一个空间复杂度为 O ( 1 ) O(1) O(1)且时间上尽可能高效的算法,重新排列 L 中的各结点,

得到线性表 L ′ = ( a 1 , a n , a 2 , a n − 1 , a 3 , a n − 2 , ⋯   ) L'=(a_1,a_n,a_2,a_{n-1},a_3,a_{n-2},\cdots) L′=(a1,an,a2,an−1,a3,an−2,⋯) 。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

#define END 33

typedef int ElemType;

typedef struct LNote {
    ElemType data;
    struct LNote *next;
} LNote, *LinkList;

void list_tail_insert(LinkList &L) {
    ElemType x;
    L = (LinkList) malloc(sizeof(LNote));
    L->next = NULL;
    scanf("%d", &x);
    LinkList s, r = L;
    while (x != END) {
        s = (LinkList) malloc(sizeof(LNote));
        s->data = x;
        r->next = s;
        r = s;
        scanf("%d", &x);
    }
    r->next = NULL;
}

void print_list(LinkList L) {
    L = L->next;
    while (L) {
        printf("%d   ", L->data);
        L = L->next;
    }
    printf("\n");
}

//双指针法遍历链表,找到链表中的中间结点
void find_middle(LinkList L, LinkList &L2) {
    L2 = (LinkList) malloc(sizeof(LNote));
    LinkList ppre, pcur; //pcur走两步,ppre走一步
    ppre = pcur = L->next;
    while (pcur) {
        pcur = pcur->next;//pcur=pcur->next->next;这种写法错误,当pcur->next=NULL,出错
        if (pcur == NULL || pcur->next == NULL) {
            break;
        }
        pcur = pcur->next;
        ppre = ppre->next;
    }
    L2->next = ppre->next; //L2指向后一半链表L2
    ppre->next = NULL;  //前一半链表在中间结点结束,指向NULL
}

//逆置L2
void reverse(LinkList &L) {
    LinkList r, s, t;
    r = L->next;
    if (r == NULL || r->next == NULL) { // L为空或只有一个结点,翻转失败
        return;
    }
    s = r->next;
    t = s->next;
    while (t) {
        s->next = r; //开始逆置
        r = s;
        s = t;
        t=t->next;
    }
    s->next = r;
    L->next->next=NULL;//原第一个结点的next为null
    L->next=s;
}

//将L与L2链表结点,轮流放入合并为新结点
void merge(LinkList L,LinkList L2){
    LinkList p,q,pcur;
    p=L->next; //始终指向L1待处理结点
    p=p->next;
    q=L2->next; //始终指向L2待处理结点
    pcur=L->next;//始终指向组合后链表的最后一个结点

    while (p&&q){ //原列表中至少有三个结点
        pcur->next=q;
        q=q->next;
        pcur=pcur->next;

        pcur->next=p;
        p=p->next;
        pcur=pcur->next;
    }
    if(p!=NULL){
        pcur->next=p;
    }
    if(q!=NULL){
        pcur->next=q;
    }
}
int main() {
    LinkList L;//链表头,是结构体指针类型
    LinkList L2 = NULL;//寻找中间结点,并返回第二条链表;加不加NULL都行
    LinkList search;//用来存储拿到的某一个节点

    list_tail_insert(L);
    printf("------L initialize is-------------------\n");
    print_list(L);

    find_middle(L, L2); //初试试卷只要写明下面三个子函数就行,main上面那几行可不写
    printf("------L1 L2 is-------------------\n");
    print_list(L);
    print_list(L2);

    reverse(L2);
    printf("------ L2 reverse is-------------------\n");
    print_list(L2);

    merge(L,L2);
    printf("------ L merge is-------------------\n");
    print_list(L);
    free(L2);
    return 0;
}
相关推荐
白毛大侠34 分钟前
理解 Go 接口:eface 与 iface 的区别及动态性解析
开发语言·网络·golang
李昊哲小课1 小时前
Python办公自动化教程 - 第7章 综合实战案例 - 企业销售管理系统
开发语言·python·数据分析·excel·数据可视化·openpyxl
Hou'1 小时前
从0到1的C语言传奇之路
c语言·开发语言
不知名的老吴1 小时前
返回None还是空集合?防御式编程的关键细节
开发语言·python
Tanecious.1 小时前
蓝桥杯备赛:Day6-B-小紫的劣势博弈 (牛客周赛 Round 85)
c++·蓝桥杯
迈巴赫车主1 小时前
蓝桥杯3500阶乘求和java
java·开发语言·数据结构·职场和发展·蓝桥杯
流云鹤2 小时前
Codeforces Round 1090 (Div. 4)
c++·算法
小菜鸡桃蛋狗2 小时前
C++——string(上)
开发语言·c++
wljy12 小时前
第十三届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(个人见解,已完结)
c语言·c++·算法·蓝桥杯·stl
chushiyunen2 小时前
python pygame实现贪食蛇
开发语言·python·pygame