• 链表反转和找出链表中间节点


    typedef struct _list_node
    {
        double
     keyVal;
        struct _list_node *
    next;
     }ListNode;

    Q1 单链表的反序


      ListNode* reverseList(ListNode* head)
     {
         ListNode *p1, *p2 , *p3;
         //链表为空,或是单结点链表直接返回头结点
         if (head == NULL || head->next == NULL)
          {
              return head;
          }
          p1 = head;
         p2 = head->next;
         while (p2 != NULL)
         {
             p3 = p2->next;
             p2->next = p1;
             p1 = p2;
             p2 = p3;
         }
         head->next = NULL;
         head = p1;
     
         return head;
     }

    Q2 找出链表的中间元素


     1 ListNode* find_midlist(ListNode* head)
     2 
    {
     3     ListNode *p1, *
    p2;
     4 
        
     5     if (head == NULL || head->next ==
     NULL)
     6 
        {
     7         return
     head;
     8 
        }
     9     p1 = p2 =
     head;
    10     while (1
    )
    11 
        {
    12         if (p2->next != NULL && p2->next->next !=
     NULL)
    13 
            {
    14             p2 = p2->next->
    next;
    15             p1 = p1->
    next;
    16 
            }
    17         else

    18         {
    19             break
    ;
    20 
            }
    21 
        }
    22     return
     p1;
    23 }

    思路分析:

     链表的一个比较大的特点用一句广告语来说就是“不走回头路”,不能实现随机存取(random access)。如果我们想要找一个数组a的中间元素,直接a[len/2]就可以了,但是链表不行,因为只有a[len/2 - 1] 知道a[len/2]在哪儿,其他人不知道。因此,如果按照数组的做法依样画葫芦,要找到链表的中点,我们需要做两步(1)知道链表有多长(2)从头结点开始顺序遍历到链表长度的一半的位置。这就需要1.5n(n为链表的长度)的时间复杂度了。有没有更好的办法呢?有的。想法很简单:两个人赛跑,如果A的速度是B的两倍的话,当A到终点的时候,B应该刚到中点。这只需要遍历一遍链表就行了,还不用计算链表的长度。

     上面的代码就体现了这个想法。

  • 相关阅读:
    bzoj3530 [SDOI2014]数数
    bzoj3940 Censoring
    线性代数基础
    hdu1085 Holding Bin-Laden Captive!
    hdu1028 Ignatius and the Princess III
    luogu2000 拯救世界
    博弈论入门
    树hash
    luogu2173 [ZJOI2012]网络
    luogu1501 [国家集训队]Tree II
  • 原文地址:https://www.cnblogs.com/yitianke/p/3031646.html
Copyright © 2020-2023  润新知