链表面试题之常规题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 

利用参数,少用一个节点的空间

 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 }

 

使用递归来实现反转链表

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 

 

如果有空,还会有一篇讨论约瑟夫环问题。

这里还有一道题目可以作为思考题。

题目如下:

有一个特殊的链表,其中每个节点不但有指向下一个节点的指针pNext,还有一个指向链表中任意节点的指针pRand,如何copy这个链表?

链表节点为

1 struct   List   
2 {   
3     struct   List*   data;   
4     struct   List*   next;   
5 };  

其中next为下一个节点,data指向链表中的随机一个节点。

大家看看如何实现呢?

对了,要求如下

1、新链表中节点的data指向新链表中对应节点,而非原链表中对应节点。 

2、不能用缓存(如数组等),可用临时变量

3、必须为O(n)

posted on 2009-10-29 19:24  cnyao  阅读(710)  评论(0编辑  收藏  举报