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

本文介绍了单链表的反序操作及中间元素查找方法,通过双指针技巧实现高效算法,无需计算链表长度,简化操作流程。
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应该刚到中点。这只需要遍历一遍链表就行了,还不用计算链表的长度。

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

转载于:https://www.cnblogs.com/yitianke/p/3031646.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值