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();
    }
  • 相关阅读:
    修改科目的字段状态组-OBC4
    采购收货-对于物料,在工厂、库存地点中不存在物料主数据
    采购收货
    新建工厂
    采购订单收货提示,T169P表不存在
    维护工厂日历
    开始创建物料没有选择会计视图,需要怎么维护
    拓端数据tecdat|R语言分布滞后线性和非线性模型(DLMs和DLNMs)分析时间序列数据
    拓端数据tecdat|R语言分布滞后非线性模型(DLNM)研究发病率,死亡率和空气污染示例
    拓端数据tecdat|R语言中实现广义相加模型GAM和普通最小二乘(OLS)回归
  • 原文地址:https://www.cnblogs.com/silentNight/p/14001999.html
Copyright © 2011-2022 走看看