链表面试题之常规题1 -- 反转链表
反转链表其实在前面的系列中已经写过程序了,现在只是将其单独提出来,列在这里。
主要就是使用额外的指针来标识新链表的头,现在正在处理的链表,以及链表的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)