1. 程式人生 > 實用技巧 >單鏈表 刪除倒數第m個元素的實現

單鏈表 刪除倒數第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(); }