链表倒置(不使用栈)

思路步骤:【括号()里面表示后续结点

L:12345(5个结点)

设置p1=1(2345)

p2=2(345)//待处理的

L:1(2345)//1是倒置后的尽头,置空它的next指针

---------------

设置p1=3(45)//处理了2后剩下的

p2=2(1)//当前处理的是2,再接上已处理好的

L:12  //

p2=3(45)

-----------------

设置p1=4(5)  //处理了3剩下的

p2=3(21)  //当前处理的是3,再接上已处理好的

L:321//

p2=4(5)

-----------------

设置p1=5(NULL)

p2=4(321)  //当前处理的是4,再接上已处理好的

L:4321   //

p2=5(NULL)

-----------------

设置p1=NULL

p2=5(4321)

L:54321  //当前处理的是4,再接上已处理好的

p2=NULL

-----------------判断到p1=NULL结束

#include <stdio.h>
#include <stdlib.h>
//不使用栈进行链表倒置

//创建一个链表
typedef struct Node
{
    int data;
    struct Node *next;
} Node, *LinkList;

//有头结点
void createLinkList1(int arr[], int len, LinkList L)
{
    Node *p = L;
    for (int i = 0; i < len; i++)
    {
        Node *n = (Node *)malloc(sizeof(Node));
        n->data = arr[i];
        n->next = NULL;

        p->next = n;
        p = n;
    }
}

//有头结点的转置
void inverse1(LinkList L)
{
    Node *p1 = L->next;   //第一个
    Node *p2 = p1->next;  //第二个
    L->next->next = NULL; //第1个=倒置后的最后1个,此结点没有下一个结点的指针,如2->1[->2->3..5]不成立
    while (p1)
    {
        p1 = p2->next;      //指向没有处理的结点的首个指针,如3->4->5、4->5
        p2->next = L->next; //正在进行倒置处理的结点的下一个指向原来头结点的后一个,让它接上,如2后面接上1、3后面接上2->1
        L->next = p2;       //当前结点进行倒序,如头结点以外变成2->1、3->2->1
        p2 = p1;            //p2继续指向没有处理过的结点,如3->4->5、4->5
    }
}

//无头结点
void createLinkList2(int arr[], int len, LinkList L)
{
    Node *p = L;
    for (int i = 1; i < len; i++)
    {
        Node *n = (Node *)malloc(sizeof(Node));
        n->data = arr[i];
        n->next = NULL;

        p->next = n;
        p = n;
    }
}
//无头结点的转置,表头指针位置会被修改,要么使用引用要么返回结果重新接收
void inverse2(LinkList &L)
{
    Node *p1 = L;
    Node *p2 = p1->next;
    L->next = NULL;
    while (p1)
    {
        p1 = p2->next;
        p2->next = L;
        L = p2;
        p2 = p1;
    }
}

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

int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    //有头结点
    LinkList L1 = (LinkList)malloc(sizeof(Node));
    createLinkList1(arr, 5, L1);
    display(L1);
    inverse1(L1);
    display(L1);
    //无头结点
    LinkList L2 = (Node *)malloc(sizeof(Node));
    L2->data = arr[0];
    createLinkList2(arr, 5, L2);
    display(L2);
    inverse2(L2);
    display(L2);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值