反转链表其实在前面的系列中已经写过程序了,现在只是将其单独提出来,列在这里。
主要就是使用额外的指针来标识新链表的头,现在正在处理的链表,以及链表的next节点。
题目:将链表按照逆序排列
可以使用非递归,也就是循环遍历的方法
1
linknode
*
reverse(linknode
*
head)
2 {
3 linknode * newlist = NULL;
4 linknode * curr = head;
5 while (curr)
6 {
7 // 定义一个指向当前节点下一个节点的指针
8 linknode * next = curr -> next;
9 // 将当前节点的next指针进行反转
10 curr -> next = newlist;
11 // 将新的反转后的链表的头节点移动到当前节点
12 newlist = curr;
13 // 移动到下一个节点,准备处理
14 curr = next;
15 }
16 return newlist;
17 }
18
2 {
3 linknode * newlist = NULL;
4 linknode * curr = head;
5 while (curr)
6 {
7 // 定义一个指向当前节点下一个节点的指针
8 linknode * next = curr -> next;
9 // 将当前节点的next指针进行反转
10 curr -> next = newlist;
11 // 将新的反转后的链表的头节点移动到当前节点
12 newlist = curr;
13 // 移动到下一个节点,准备处理
14 curr = next;
15 }
16 return newlist;
17 }
18
利用参数,少用一个节点的空间
1
linknode
*
reverse(linknode
*
head)
2 {
3 linknode * newlist = NULL;
4 linknode * curr = head;
5 while (curr)
6 {
7 head = curr -> next;
8 curr -> next = newlist;
9 newlist = curr;
10 curr = head;
11 }
12 return newlist;
13 }
2 {
3 linknode * newlist = NULL;
4 linknode * curr = head;
5 while (curr)
6 {
7 head = curr -> next;
8 curr -> next = newlist;
9 newlist = curr;
10 curr = head;
11 }
12 return newlist;
13 }
使用递归来实现反转链表
1
linknode
*
reverse(linknode
*
oldlist, linknode
*
newlist)
2 {
3 if (oldlist == NULL)
4 return newlist;
5 linknode * next = oldlist -> next;
6 oldlist -> next = newlist;
7 reverse(next,oldlist);
8 }
9
2 {
3 if (oldlist == NULL)
4 return newlist;
5 linknode * next = oldlist -> next;
6 oldlist -> next = newlist;
7 reverse(next,oldlist);
8 }
9
如果有空,还会有一篇讨论约瑟夫环问题。
这里还有一道题目可以作为思考题。
题目如下:
有一个特殊的链表,其中每个节点不但有指向下一个节点的指针pNext,还有一个指向链表中任意节点的指针pRand,如何copy这个链表?
链表节点为
1
struct
List
2 {
3 struct List * data;
4 struct List * next;
5 };
2 {
3 struct List * data;
4 struct List * next;
5 };
其中next为下一个节点,data指向链表中的随机一个节点。
大家看看如何实现呢?
对了,要求如下
1、新链表中节点的data指向新链表中对应节点,而非原链表中对应节点。
2、不能用缓存(如数组等),可用临时变量
3、必须为O(n)