life02

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  197 随笔 :: 3 文章 :: 37 评论 :: 0 Trackbacks
http://www.cnblogs.com/iceocean/articles/1775848.html

题目:输入一个链表的头结点,反转该链表,并返回反转后链表的头结点。链表结点定义如下:
struct ListNode
{
      int        m_nKey;
       ListNode* m_pNext;
};
分析:这是一道广为流传的微软面试题。由于这道题能够很好的反应出程序员思维是否严密,在微软之后已经有很多公司在面试时采用了这道题。
为了正确地反转一个链表,需要调整指针的指向。与指针操作相关代码总是容易出错的,因此最好在动手写程序之前作全面的分析。在面试的时候不急于动手而是一开始做仔细的分析和设计,将会给面试官留下很好的印象,因为在实际的软件开发中,设计的时间总是比写代码的时间长。与其很快地写出一段漏洞百出的代码,远不如用较多的时间写出一段健壮的代码。
为了将调整指针这个复杂的过程分析清楚,我们可以借助图形来直观地分析。假设下图中lmn是三个相邻的结点:
aßbßßl  mànà
假设经过若干操作,我们已经把结点l之前的指针调整完毕,这些结点的m_pNext指针都指向前面一个结点。现在我们遍历到结点m。当然,我们需要把调整结点的m_pNext指针让它指向结点l。但注意一旦调整了指针的指向,链表就断开了,如下图所示:
aßbßlßm  nà
因为已经没有指针指向结点n,我们没有办法再遍历到结点n了。因此为了避免链表断开,我们需要在调整mm_pNext之前要把n保存下来。
接下来我们试着找到反转后链表的头结点。不难分析出反转后链表的头结点是原始链表的尾位结点。什么结点是尾结点?就是m_pNext为空指针的结点。
基于上述分析,我们不难写出如下代码:
///////////////////////////////////////////////////////////////////////
// Reverse a list iteratively
// Input: pHead - the head of the original list
// Output: the head of the reversed head
///////////////////////////////////////////////////////////////////////
ListNode* ReverseIteratively(ListNode* pHead)
{
       ListNode* pReversedHead = NULL;
       ListNode* pNode = pHead;
       ListNode* pPrev = NULL;
      while(pNode != NULL)
       {
            // get the next node, and save it at pNext
             ListNode* pNext = pNode->m_pNext;
            // if the next node is null, the currect is the end of original
            // list, and it's the head of the reversed list
            if(pNext == NULL)
                   pReversedHead = pNode;

            // reverse the linkage between nodes
             pNode->m_pNext = pPrev;

            // move forward on the the list
             pPrev = pNode;
             pNode = pNext;
       }

      return pReversedHead;
}
(转载

List ReverseList(List head)  
{  
    
if(head->next == NULL || head->next->next == NULL)    
    
{  
       
return head;   /*链表为空或只有一个元素则直接返回*/  
    }
  
  
    ListNode 
*= NULL,  
             
*= head->next,  
             
*= head->next->next;  
    
while(q != NULL)  
    
{          
      t 
= q->next;  
      q
->next = p;  
      p 
= q;  
      q 
= t;  
    }
  
  
    
/*此时q指向原始链表最后一个元素,也是逆转后的链表的表头元素*/  
    head
->next->next = NULL;  /*设置链表尾*/  
    head
->next = p;           /*调整链表头*/  
    
return head;  
}
  
  


posted on 2012-02-21 16:32 life02 阅读(288) 评论(0)  编辑 收藏 引用 所属分类: 笔试

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理