现在的位置: 首页 > 综合 > 正文

找出单向链表的倒数第m个元素

2018年07月16日 ⁄ 综合 ⁄ 共 1468字 ⁄ 字号 评论关闭
链表节点:
class Node
{
public:
   
int       
data;
    Node
*   
next;

public:
    Node(
int n)
: data(n), next(
0)
   
{
   
}


    Node() : data(
0),
next(
0)
   
{
   
}


    Node
* InsertAfter(int _data
)
   
{
        Node
* newnode= new Node(_data);

        newnode
->next= next;
        next
= newnode;

       
return newnode;
   
}

}
;

低效的查找算法:

Node* FindMToLastNode(Node* pHead,int m)
{
   
// 第一次遍历,获取链表的计数
   
Node
* pCurrent= pHead;
   
int nCount = 0;
   
while (pCurrent)
   
{
       
++nCount;
        pCurrent
= pCurrent->next;
   
}


   
// 防止越界
   if (m > nCount) return0;

   
// 第二遍遍历,获取倒数第m个节点,也就是顺数滴n个节点
   int n = nCount - m+ 1;
    nCount
= 0;
    pCurrent
= pHead;
   
while (pCurrent)
   
{
       
++nCount;
       
if (nCount == n)
       
{
           
return pCurrent;
       
}


        pCurrent
= pCurrent->next;
   
}


   
return 0;
}

 


这个算法很低效,要循环列表两次,从时间上来说,消耗很大.从空间上,需要3个临时变量,消耗也有点大.

高效的查找算法:

 
 

  1. Node* FindMToLastNode(Node* pHead, int m)  
  2. {  
  3.         // 查找到第m个元素  
  4.     Node* pCurrent = pHead;  
  5.     for (int i = 0; i < m; ++i)  
  6.     {  
  7.         if (pCurrent)  
  8.         {  
  9.             pCurrent = pCurrent->next;  
  10.         }  
  11.         else  
  12.         {  
  13.             return NULL;  
  14.         }  
  15.     }  
  16.     // 一起继续遍历到链表尾部,  
  17.     // 现在pFind和pCurrent之间间隔了m个元素,  
  18.     // 所以,当pCurrent遍历到尾部的时候,  
  19.     // pFind就到了倒数第m个元素的位置上.  
  20.       
  21.     Node* pFind = pHead;  
  22.     while (pCurrent)  
  23.     {  
  24.         pFind        = pFind->next;  
  25.         // 间隔m个元素  
  26.         pCurrent    = pCurrent->next;  
  27.     }  
  28.   
  29.     return pFind;  
  30.  }  

 
这个算法果然精妙!空间上只需要开销两个临时变量,时间上只需要循环链表一遍,也就是O(n)!

抱歉!评论已关闭.