zoukankan      html  css  js  c++  java
  • 反转链表

    题目:输入一个链表的头结点,反转该链表,并返回反转后链表的头结点。链表结点定义如下:
    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;
    }
    扩展:本题也可以递归实现。感兴趣的读者请自己编写递归代码。


    struct linka
    {
    	int data;
    	linka* next;
    };
    
    void reverse(linka*& head)
    {
    	if(head ==NULL)
    		return;
    	linka*pre, *cur, *ne;
    	pre=head;
    	cur=head->next;
    	while(cur)
    	{
    		ne = cur->next;
    		cur->next = pre;
    		pre = cur;
    		cur = ne;
    	}
    	head->next = NULL;
    	head = pre;
    }
    

      


    FROM:

    http://hi.baidu.com/fumble/blog/item/b56e5d60029638dc8db10dc4.html

    http://www.douban.com/note/81699216/

  • 相关阅读:
    嵌入式GUI FTK介绍(7)主题
    嵌入式GUI FTK介绍(2)两个小应用程序
    嵌入式GUI FTK介绍(8)编译/运行PC模拟版本
    嵌入式GUI FTK介绍(5)在多平台上运行
    嵌入式GUI FTK介绍(4)脚本语言绑定
    嵌入式GUI FTK介绍(3)XML界面描述语言
    活动图
    ASP.NET程序中常用的三十三种代码
    Server的Transfer和Response的Redirect (转)
    .net 点击刷新验证码问题
  • 原文地址:https://www.cnblogs.com/dartagnan/p/2177926.html
Copyright © 2011-2022 走看看