王道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;
}
相关推荐
ytttr87318 分钟前
隐马尔可夫模型(HMM)MATLAB实现范例
开发语言·算法·matlab
天远Date Lab20 分钟前
Python实战:对接天远数据手机号码归属地API,实现精准用户分群与本地化运营
大数据·开发语言·python
listhi52022 分钟前
基于Gabor纹理特征与K-means聚类的图像分割(Matlab实现)
开发语言·matlab
qq_433776421 小时前
【无标题】
开发语言·php
AlenTech1 小时前
160. 相交链表 - 力扣(LeetCode)
数据结构·leetcode·链表
会周易的程序员1 小时前
多模态AI 基于工业级编译技术的PLC数据结构解析与映射工具
数据结构·c++·人工智能·单例模式·信息可视化·架构
Davina_yu1 小时前
Windows 下升级 R 语言至最新版
开发语言·windows·r语言
阿珊和她的猫2 小时前
IIFE:JavaScript 中的立即调用函数表达式
开发语言·javascript·状态模式
listhi5202 小时前
卷积码编码和维特比译码的MATLAB仿真程序
开发语言·matlab
yuan199972 小时前
基于主成分分析(PCA)的故障诊断MATLAB仿真
开发语言·matlab