6-3 单链表逆转c语言,单链表逆转(数据结构)

这题看了很多个版本,但基本看不懂,毕竟最怕就是没有注释自己来推,更准确点说,数据结构需要的是思路的传达而不是直接给个代码。最后在一个博主那里看到了他的思路详解,感觉需要学习一下。

6-1 单链表逆转(20 分)

本题要求实现一个函数,将给定的单链表逆转。

函数接口定义:

List Reverse( List L );

其中List结构定义如下:

typedef struct Node *PtrToNode;

struct Node{

ElementType Data; /* 存储结点数据 */

PtrToNode Next; /* 指向下一个结点的指针 */

};

typedef PtrToNode List; /* 定义单链表类型 */

L是给定单链表,函数Reverse要返回被逆转后的链表。

#include #include typedef int ElementType;

typedef struct Node *PtrToNode;

struct Node {

ElementType Data;

PtrToNode Next;

};

typedef PtrToNode List;

List Read(); /* 细节在此不表 */

void Print( List L ); /* 细节在此不表 */

List Reverse( List L );

int main()

{

List L1, L2;

L1 = Read();

L2 = Reverse(L1);

Print(L1);

Print(L2);

return 0;

}

/* 你的代码将被嵌在这里 */

输入样例:

5

1 3 4 5 2

输出样例:

1

2 5 4 3 1

这题的编码主要是在不清楚如何接收数据条件下去打,一开始有些好奇他的输入会不会对于我后面的代码有影响,不过其实多想了,毕竟给你的是已经有数据的链表L1,你直接返回修改后的链表就OK。但思路也会有一些需要琢磨的地方,接下来我就详细说说这思路。

(1).开始的时候,创建一个指针域空的指针为Prev, 指向内容为空(NULL),当List Reverse( List L );这个函数接收的链表内容为A,B,C,D(为了简便我用字母,里面定义是整型,但思路一样适用),如下图:

e7ca817d3e6857b8ccfdf71c6dc43f0a.png

第一步,用 L->Next  指向 Prev,  切断 L->Next 与B直接的联系,这样一来就变成了下面的样子。

用代码实现就是: L->Next = Prev;

(2).有了第一步,就可以想到第二部怎么做了,但还需要注意一些细节,我们需要修改Prev的指针指向的位置,还有指针L指向的位置,为的是下一步将 B 也连接到 A 指针的后面,如下图:

此时将L重新指向原来的链表的第一个位置,但原来的链表少了一个A,此时就指向了B,让temp指向下C。用代码实现就是:

Prev = L;

L = Temp;

Temp = L->Next;

在这里就实现两个新的链表。

(3)之后就是继续按照第一步走,将L->Next=Pre; 就是让B的Next指针指向A,如下图:

以此类推,相信你应该明白如何移动D了。最后就是结束条件了,在这里可以用 Temp 或 L ,正确的是该用

while(L)来退出,至于有人会误用Temp甚至L->Next,大多数因为一开始就有先写条件的习惯,我的建议是退出条件最后写,不容易写错。那么具体的代码实现如下了。

List Reverse( List L )

{

List Temp, Prev;

Prev = NULL;

while(L)

{

Temp = L->Next;

L->Next = Prev;

Prev = L;

L = Temp;

}

return Prev;

}

而全部代码如果想具体看完也有,还有递归的思路也有

这个博主的思路很详细,我就是从这位博主这里学习的 ,超级感谢这位博主 点击打开链接

这个是具体代码,最好只用来调试。

#include#includetypedef int ElementType;

typedef struct Node *PtrToNode;

struct Node {

ElementType Data;

PtrToNode Next;

};

typedef PtrToNode List;

List Read();

void Print(List L);

List Reverse(List L);

int main()

{

List L1, L2;

L1 = Read();

L2 = Reverse(L1);

Print(L1);

Print(L2);

return 0;

}

/* 建立链表 */

List Read()

{

List head = NULL;

List current;

List prev = NULL;

int len = 0;

scanf("%d", &len);

if (len == 0)   return NULL;

while (len--)

{

current = (List)malloc(sizeof(struct Node));

if (head == NULL)

head = current;

else

prev->Next = current;

current->Next = NULL;

scanf("%d", &current->Data);

prev = current;

}

return head;

}

void Print(List L)

{

List p = L;

List s = L;

List temp;

if (p == NULL)

printf("NULL");

else

printf("\n");

while (p!=NULL) {

printf("%d ", p->Data);

p = p->Next;

}

}

List Reverse( List L )

{

List Temp, Prev;

Prev = NULL;

while(L)

{

Temp = L->Next;

L->Next = Prev;

Prev = L;

L = Temp;

}

return Prev;

}

19317b1e09f28e21de57ad3ffb5835a3.png

编译器:DEV C++

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值