这题看了很多个版本,但基本看不懂,毕竟最怕就是没有注释自己来推,更准确点说,数据结构需要的是思路的传达而不是直接给个代码。最后在一个博主那里看到了他的思路详解,感觉需要学习一下。
本题要求实现一个函数,将给定的单链表逆转。
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
(1).开始的时候,创建一个指针域空的指针为Prev, 指向内容为空(NULL),当List Reverse( List L );这个函数接收的链表内容为A,B,C,D(为了简便我用字母,里面定义是整型,但思路一样适用),如下图:
第一步,用 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
#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;
}
/* 建立链表 */
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", ¤t->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;
}
编译器:DEV C++