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

链表节点:
找出单向链表的倒数第m个元素class Node
找出单向链表的倒数第m个元素{
找出单向链表的倒数第m个元素public:
找出单向链表的倒数第m个元素    int        data;
找出单向链表的倒数第m个元素    Node*    next;
找出单向链表的倒数第m个元素
找出单向链表的倒数第m个元素public:
找出单向链表的倒数第m个元素    Node(int n) : data(n), next(0)
找出单向链表的倒数第m个元素    {
找出单向链表的倒数第m个元素    }

找出单向链表的倒数第m个元素
找出单向链表的倒数第m个元素    Node() : data(0), next(0)
找出单向链表的倒数第m个元素    {
找出单向链表的倒数第m个元素    }

找出单向链表的倒数第m个元素
找出单向链表的倒数第m个元素    Node* InsertAfter( int _data )
找出单向链表的倒数第m个元素    {
找出单向链表的倒数第m个元素        Node* newnode = new Node(_data);
找出单向链表的倒数第m个元素
找出单向链表的倒数第m个元素        newnode->next = next;
找出单向链表的倒数第m个元素        next = newnode;
找出单向链表的倒数第m个元素
找出单向链表的倒数第m个元素        return newnode;
找出单向链表的倒数第m个元素    }

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


低效的查找算法:
找出单向链表的倒数第m个元素Node* FindMToLastNode(Node* pHead, int m)
找出单向链表的倒数第m个元素{
找出单向链表的倒数第m个元素    // 第一次遍历,获取链表的计数
找出单向链表的倒数第m个元素
    Node* pCurrent = pHead;
找出单向链表的倒数第m个元素    int nCount = 0;
找出单向链表的倒数第m个元素    while (pCurrent)
找出单向链表的倒数第m个元素    {
找出单向链表的倒数第m个元素        ++nCount;
找出单向链表的倒数第m个元素        pCurrent = pCurrent->next;
找出单向链表的倒数第m个元素    }

找出单向链表的倒数第m个元素
找出单向链表的倒数第m个元素    // 防止越界
找出单向链表的倒数第m个元素
    if (m > nCount) return 0;
找出单向链表的倒数第m个元素
找出单向链表的倒数第m个元素    // 第二遍遍历,获取倒数第m个节点,也就是顺数滴n个节点
找出单向链表的倒数第m个元素
    int n = nCount - m + 1;
找出单向链表的倒数第m个元素    nCount = 0;
找出单向链表的倒数第m个元素    pCurrent = pHead;
找出单向链表的倒数第m个元素    while (pCurrent)
找出单向链表的倒数第m个元素    {
找出单向链表的倒数第m个元素        ++nCount;
找出单向链表的倒数第m个元素        if (nCount == n)
找出单向链表的倒数第m个元素        {
找出单向链表的倒数第m个元素            return pCurrent;
找出单向链表的倒数第m个元素        }

找出单向链表的倒数第m个元素
找出单向链表的倒数第m个元素        pCurrent = pCurrent->next;
找出单向链表的倒数第m个元素    }

找出单向链表的倒数第m个元素
找出单向链表的倒数第m个元素    return 0;
找出单向链表的倒数第m个元素}
这个算法很低效,要循环列表两次,从时间上来说,消耗很大.从空间上,需要3个临时变量,消耗也有点大.


高效的查找算法:
找出单向链表的倒数第m个元素Node* FindMToLastNode(Node* pHead, int m)
找出单向链表的倒数第m个元素{
找出单向链表的倒数第m个元素    // 查找到第m个元素
找出单向链表的倒数第m个元素
    Node* pCurrent = pHead;
找出单向链表的倒数第m个元素    for (int i = 0; i < m; ++i)
找出单向链表的倒数第m个元素    {
找出单向链表的倒数第m个元素        if (pCurrent)
找出单向链表的倒数第m个元素        {
找出单向链表的倒数第m个元素            pCurrent = pCurrent->next;
找出单向链表的倒数第m个元素        }

找出单向链表的倒数第m个元素        else
找出单向链表的倒数第m个元素        {
找出单向链表的倒数第m个元素            return NULL;
找出单向链表的倒数第m个元素        }

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

找出单向链表的倒数第m个元素
找出单向链表的倒数第m个元素    // 一起继续遍历到链表尾部,
找出单向链表的倒数第m个元素    
// 现在pFind和pCurrent之间间隔了m个元素,
找出单向链表的倒数第m个元素    
// 所以,当pCurrent遍历到尾部的时候,
找出单向链表的倒数第m个元素    
// pFind就到了倒数第m个元素的位置上.
找出单向链表的倒数第m个元素
    Node* pFind = pHead;
找出单向链表的倒数第m个元素    while (pCurrent)
找出单向链表的倒数第m个元素    {
找出单向链表的倒数第m个元素        pFind        = pFind->next;
找出单向链表的倒数第m个元素        // 间隔m个元素
找出单向链表的倒数第m个元素
        pCurrent    = pCurrent->next;
找出单向链表的倒数第m个元素    }

找出单向链表的倒数第m个元素
找出单向链表的倒数第m个元素    return pFind;
找出单向链表的倒数第m个元素}
这个算法果然精妙!空间上只需要开销两个临时变量,时间上只需要循环链表一遍,也就是O(n)!
我太笨了,居然没有想到如此绝妙的算法.
上一篇:redis命令总结


下一篇:oracle中一些sql以及存储过程小积累(转)