6-1 单链表逆转 (20 point(s))
本题要求实现一个函数,将给定的单链表逆转。
##函数接口定义:
List Reverse( List L );
其中List结构定义如下:
typedef struct Node PtrToNode;
struct Node {
ElementType Data; / 存储结点数据 /
PtrToNode Next; / 指向下一个结点的指针 /
};
typedef PtrToNode List; / 定义单链表类型 */
L是给定单链表,函数Reverse要返回被逆转后的链表。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
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
居中的图片:
##代码入下
**
方法一:就地逆转或者说双链表逆转
思路在注释中 这种方法是最常用的方法 时间复杂度O(n) 空间复杂度
如果上面的没看懂就看下面的分析
总体分为循环核心操作与循环连接操作.
具体来说就是新建一个结构体指针prev,让其初始时指向NULL,然后让链表L的第一个元素指向prev(NULL),这样做形象地说就是将第一个元素从原始链表L剪下,并粘在了prev的前面,形成了新的链表List2;下一次循环的核心操作也是如此,即将第二个元素从被剪后的原始链表中(我们记作List’,L的第二个元素也就是List’的第一个元素)剪下,粘到List2上;但需要注意此时L的指向已经发生改变,故不能直接进行下一次循环操作,还需要一些循环连接操作,使循环得以进行.
那循环连接操作应该怎样做呢?
我们需要一个引入临时指针,在每次循环中指向着List’(第一次循环就是L)的第二个元素.这样,我们就可以保证每一次循环之后,我们都能找到List’的第一个元素,这是为了我们下一次的"剪"做铺垫.
那贴呢?由于我们并没有移动prev,它还指着NULL呢,于是我们就必须让prev也同时往前指,每次循环中都指向刚刚粘过来的元素.,
最后我们只要让L再指向刚刚临时指针temp指向的位置,就能保证下一次能直接把L所指元素直接剪下来拉.这样循环连接操作就完成拉>_
**
代码如下:
//
List Reverse( List L )
{
List prev=NULL;//初始时先让prev指向NULL
List temp=L;//定义一个临时指针
while(temp){
temp=temp->next;//让临时指针每次循环时指向下一次要剪掉的元素,这是循环连接操作
L->next=prev; //将L/L'的第一个元素从L/L'中剪下,粘到L2上,并指向prev,这是循环核心操作
prev=L;//将prev往前指,使得下一次剪下来的元素能够粘到新链表L2的头,这是循环连接操作
L=temp;//L返回临时指针所指位置,使得下一次可以直接将其剪下,这是循环连接操作
}
return prev;
}
第二种方法:创建新节点法
具体来说就是,新建一个节点,然后让该节点的值等于链表第一个元素的值;再通过遍历原时链表,每次得到下一节点的值,再利用头插法插入到新链表的前面.这种思路有暴力解决内味儿了,时间复杂度O(n),空间复杂度O(n)
List Reverse(List L)
{
if (!L) exit(0);
List head = L;
List t;
t = (List)malloc(sizeof(Node));
t->Next = NULL;
while (head&&head->Next)
{
t->Data = head->Data;
head = head->Next;
List q;
q = (List)malloc(sizeof(Node));
q->Data = head->Data;
q->Next = t;
t = q;
}
return t;
}
## 第三种方法:递归
递归的核心思想是将原问题化为更小规模的子问题;
所以我们先从简单情况入手
假设原链表只有一个结点p1,我们只需返回p1结点即可
假设原链表有两个...
生病了 回头补思路