zoukankan      html  css  js  c++  java
  • 单链表 删除倒数第m个元素的实现

    #include<iostream>
    #include<iomanip>
    using namespace std;
    
    struct Node
    {
        public:
            Node():val(0),next(NULL){}
            Node(int v):val(v),next(NULL){}
            int val;
            Node* next;
    };
    
    class NodeManager
    {
        public:
            NodeManager(){pHead = NULL;};
    
            //尾插法插入一个元素
            void push_back(int val)
            {
                //第一个元素涉及head指针指向,所以单独处理
                if (pHead == NULL)
                {
                    pHead = new Node(val);
                }
                else//非第一个元素找到队尾插入此元素
                {
                    Node* pNewNode = new Node(val);
                    Node* pCurrent = pHead;
                    while(pCurrent->next)
                    {
                        pCurrent = pCurrent->next;
                    }
    
                    pCurrent->next = pNewNode;
    
                }
            }
    
            virtual ~NodeManager()
            {
                Node* pCurrent = pHead;
    
                while(pCurrent)
                {
                    pHead = pCurrent->next;
    
                    cout << "delet address: " << hex << pCurrent << endl;
                    delete pCurrent;
                    pCurrent = pHead;
                }
            }
    
            void showList()
            {
                Node* pCurrent = pHead;
                while(pCurrent)
                {
                    cout<< "val = " << pCurrent->val << "  myAddress = 0x" << hex << pCurrent << "    nextAddress = 0x" << hex << pCurrent->next << dec << endl;
                    pCurrent = pCurrent->next;
                }
            }
    
            int getListNumber() //获取链表节点长度
            {
                int nTotalNum = 0;
                Node* pCurrent = pHead;
                while(pCurrent)
                {
                    pCurrent = pCurrent->next;
                    ++nTotalNum;
                }
                return nTotalNum;
            }
    
            Node* removeNthFromEnd(int n)  //用普通方法进行删除倒数第n个元素的处理
            {
                //计数倒数第n个是整数第几个
                int nTotalNum = getListNumber();
                int nObjNum = nTotalNum -n +1;
                cout << "nObjNum = " << nObjNum << endl;
    
                //删除第一个元素特别, 要动head指针的位置 ,所以特别拎出来处理
                if (nObjNum == 1)
                {
                    Node* pObj = pHead;
                    pHead = pObj->next;
                    delete pObj; pObj = NULL;
                    return pHead;
                }
    
                //找到第n-1个元素。第n个元素是待删除元素。 n-1元素执行n+1元素,然后删掉第n个元素
                Node* pCurrent = pHead; //最终指向第n-1个元素
                int nCurNum = 1;
    
                while(nCurNum != nObjNum - 1)
                {
                   pCurrent = pCurrent->next;
                   ++nCurNum;
                }
    
                Node* pObj = pCurrent->next; //第n个元素
    
                pCurrent->next = pObj->next;
                delete pObj; pObj = NULL;
    
                return pHead;
            }
    
    /* 声明两个节点指针,快指针先向前移动 N 步,然后快慢节点指针一起向前移动,直到快指针遍历完毕,此时慢节点指针会指向倒数第 N+1 个节点元素。
     注意,如果快指针向前移动 N 步已经为空,则说明我们要删除第1个元素。*/
    
            Node* removeNthFromEnd2(int n)   //只循环一遍删除一个倒数第n个元素
            {
                Node* pFast = pHead;
                Node* pSlow = pHead;
    
                int nCur = 0;
                while(nCur < n)
                {
                    if (pFast->next == NULL)
                    {
                        Node* pCurrent = pHead;
                        pHead = pHead->next;
    
                        cout << "need delete element: " << pCurrent->val << endl;
    
                        delete pCurrent;
                        pCurrent = NULL;
    
                        return pHead;
                    }
    
                    pFast = pFast->next;
                    ++nCur;
                }
    
                while(pFast->next)
                {
                    pSlow = pSlow->next;
                    pFast = pFast->next;
                }
    
                Node* pNeedDeleteNode = pSlow->next;
                pSlow->next = pNeedDeleteNode->next;
    
                cout << "need delete element: " << pNeedDeleteNode->val << endl;
                delete pNeedDeleteNode;
                pNeedDeleteNode = NULL;
    
                return pHead;
    
            }
        private:
            Node* pHead;
    };
    
    int main()
    {
        NodeManager manager;
        manager.push_back(1);
        manager.push_back(2);
        manager.push_back(3);
    
        manager.showList();
    
        cout<<"======="<<endl;
    //    manager.removeNthFromEnd(2);//删除倒数第2个
        manager.removeNthFromEnd2(3);//删除倒数第2个
        manager.showList();
    }
  • 相关阅读:
    解决ios下的微信页面背景音乐无法自动播放问题
    vue Vue-cli 笔记
    document.documentElement和document.body区别介绍
    GD库使用小结---2
    GD库使用小结---1
    踩到两只“bug”
    CI加载流程小结
    文件加载---理解一个project的第一步
    缓存的使用
    小小的分页
  • 原文地址:https://www.cnblogs.com/silentNight/p/14001999.html
Copyright © 2011-2022 走看看