单链表原地逆置

在这里插入图片描述在这里插入图片描述

List Reverse(List L1){
    /*构造链表q替代L1(使得在逆置链表的时候L1本身不变)
     * 构造完以后q指向q链表末尾
     * 而指针p全程始终指向q链表的头结点
     * 从指针p(q链表头结点处)开始进行链表逆置
     * (实际上是把q链表逐个拆开组成逆置链表):\
     * 设置指针prev置空
     * head = p->Next(第一个数据结点)
     * next = p->Next->Next(第二个数据结点)
     * 然后他俩逐个后推,将每次的head向后指向prev,prev也向前挪一位,
     * 实现prev始终指向逆置的链表第一个数据结点
     * 逆置结束之后再给prev添加一个头结点first,让L2指向first,返回L2即可完成
     * 此时:
     * q链表已经被拆成逆置链表了
     * L1不变(有头结点)
     * p只是指向原q链表的第一个头结点,
     * p->Next依然为原q链表第一个数据结点,
     * p->Next->Next = NULL(逆置的时候被拆了)
     * q依然指向原q链表的末尾,也就是逆置之后的第一个数据结点的位置
     * */
    List L2;
    List t = L1;
    List q = (List)malloc(sizeof(List));
    List p = q;
    t = t->Next;
    while(t != nullptr){
        PtrToNode s = (PtrToNode)malloc(sizeof(PtrToNode));
        s->Data = t->Data;
        q->Next = s;
        t = t->Next;
        if(t == nullptr){
            q = q->Next;
            q->Next = nullptr;
            break;
        }
        q = q->Next;
    }

    List prev = nullptr;
    List head = p->Next;
    List next = p->Next->Next;
    while(head != nullptr){
        head->Next = prev;
        prev = head;
        head = next;
        if(head == nullptr){
            break;
        }
        next = next->Next;
    }
    List first = (List)malloc(sizeof(List));
    first->Next = prev;
    L2 = first;
    return L2;
}

单链表利用栈逆置

在这里插入图片描述

List Reverse_stack(List L1){
    List L2 = (List)malloc(sizeof(PtrToNode));
    List L3 = L2;
    L1 = L1->Next;
    while(L1 != nullptr){
        List_stack.push(L1->Data);
        L1 = L1->Next;
    }
    const int List_stack_size = List_stack.size();
    for(int i = 0; i < List_stack_size; i++){
        PtrToNode s = (PtrToNode)malloc(sizeof(PtrToNode));
        s->Data = List_stack.top();
        L2->Next = s;
        L2 = L2->Next;
        List_stack.pop();
        if(List_stack.empty()){
            L2->Next = nullptr;
        }
    }
    return L3;
}

.cpp文件

//
// Created by 15328 on 2022/1/24.
//
#include<bits/stdc++.h>
using namespace std;
typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;
stack<ElementType> List_stack;
List Read(){
    List list = (List)malloc(sizeof(List));
    List p = list;
    int N;
    int value = 0;
    scanf("%d",&N);
    for(int i = 0; i < N; i++){
        PtrToNode s = (PtrToNode)malloc(sizeof(PtrToNode));
        scanf("%d",&value);
        s->Data = value;
        s->Next = nullptr;
        list->Next = s;
        list = list->Next;
    }
    return p;
}
void Print(List list){
    List p = list->Next;
    while(p != nullptr){
        printf("%d ",p->Data);
        p = p->Next;
    }
    printf("\n");
}
List Reverse(List L1){
    /*构造链表q替代L1(使得在逆置链表的时候L1本身不变)
     * 构造完以后q指向q链表末尾
     * 而指针p全程始终指向q链表的头结点
     * 从指针p(q链表头结点处)开始进行链表逆置
     * (实际上是把q链表逐个拆开组成逆置链表):\
     * 设置指针prev置空
     * head = p->Next(第一个数据结点)
     * next = p->Next->Next(第二个数据结点)
     * 然后他俩逐个后推,将每次的head向后指向prev,prev也向前挪一位,
     * 实现prev始终指向逆置的链表第一个数据结点
     * 逆置结束之后再给prev添加一个头结点first,让L2指向first,返回L2即可完成
     * 此时:
     * q链表已经被拆成逆置链表了
     * L1不变(有头结点)
     * p只是指向原q链表的第一个头结点,
     * p->Next依然为原q链表第一个数据结点,
     * p->Next->Next = NULL(逆置的时候被拆了)
     * q依然指向原q链表的末尾,也就是逆置之后的第一个数据结点的位置
     * */
    List L2;
    List t = L1;
    List q = (List)malloc(sizeof(List));
    List p = q;
    t = t->Next;
    while(t != nullptr){
        PtrToNode s = (PtrToNode)malloc(sizeof(PtrToNode));
        s->Data = t->Data;
        q->Next = s;
        t = t->Next;
        if(t == nullptr){
            q = q->Next;
            q->Next = nullptr;
            break;
        }
        q = q->Next;
    }

    List prev = nullptr;
    List head = p->Next;
    List next = p->Next->Next;
    while(head != nullptr){
        head->Next = prev;
        prev = head;
        head = next;
        if(head == nullptr){
            break;
        }
        next = next->Next;
    }
    List first = (List)malloc(sizeof(List));
    first->Next = prev;
    L2 = first;
    return L2;
}

List Reverse_stack(List L1){
    List L2 = (List)malloc(sizeof(PtrToNode));
    List L3 = L2;
    L1 = L1->Next;
    while(L1 != nullptr){
        List_stack.push(L1->Data);
        L1 = L1->Next;
    }
    const int List_stack_size = List_stack.size();
    for(int i = 0; i < List_stack_size; i++){
        PtrToNode s = (PtrToNode)malloc(sizeof(PtrToNode));
        s->Data = List_stack.top();
        L2->Next = s;
        L2 = L2->Next;
        List_stack.pop();
        if(List_stack.empty()){
            L2->Next = nullptr;
        }
    }
    return L3;
}
int main()
{
    List L1, L2, L3;
    L1 = Read();
    L2 = Reverse(L1);
    L3 = Reverse_stack(L2);
    cout << "显示输入的单链表数据:";
    Print(L1);
    cout << "单链表原地逆置:\n先构造原链表的副本,然后从头逐个拆开这个副本,逐个逆置成逆序链表: \n";
    Print(L2);
    cout << "单链表利用栈逆置:\n把第一次逆置后的链表从头逐个压栈,再逐个弹出栈赋值给新逆置链表的结点\n";
    Print(L3);
    return 0;
}


运行结果

E:\CODING__ALAN_CF\cmake-build-debug\Single_linkList_Reverse.exe
5
1 2 3 4 5
显示输入的单链表数据:1 2 3 4 5
单链表原地逆置:
先构造原链表的副本,然后从头逐个拆开这个副本,逐个逆置成逆序链表:
5 4 3 2 1
单链表利用栈逆置:
把第一次逆置后的从头逐个压栈,再逐个弹出栈赋值给新逆置链表的结点
1 2 3 4 5

进程已结束,退出代码为 0

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐