C++普通链表增删、倒序打印

实现链表的插入结点函数时,需注意传入参数pHead应该为指向链表头指针的指针,才能正确改动头指针。如:

void AddToTail(ListNode** pHead, int value);

否则如果传入参数为指针ListNode*,离开该函数作用域后pHead地址不会发生改变,如传入参数为ListNode* pHead = NULL,执行若干插入结点操作后pHead仍为NULL。

 

简单的链表结构

 

struct ListNode {
    int m_nValue;
    ListNode* m_pNext;
};

 

 

结点插入链表尾部(注意传入参数为ListNode**)

void AddToTail(ListNode** pHead, int value) {
    ListNode* pNew = new ListNode();
    pNew->m_nValue = value;
    pNew->m_pNext = NULL;
    if(*pHead == NULL) {
        *pHead = pNew;
    } else {
        ListNode* pIndex = *pHead;
        while(pIndex->m_pNext != NULL)
            pIndex = pIndex->m_pNext;
        pIndex->m_pNext = pNew;
    }
}

 

时间效率为O(n)的删除结点

void RemoveNode(ListNode** pHead, int value) {
    if(pHead == NULL || *pHead == NULL)
        return;
    ListNode* pToBeDeleted = NULL;
    if((*pHead)->m_nValue == value) {
        pToBeDeleted = *pHead;
        *pHead = (*pHead)->m_pNext;
    } else {
        ListNode* pIndex = *pHead;
        while (pIndex->m_pNext != NULL && pIndex->m_pNext->m_nValue != value)
            pIndex = pIndex->m_pNext;
        if(pIndex->m_pNext != NULL && pIndex->m_pNext->m_nValue == value) {
            pToBeDeleted = pIndex->m_pNext;
            pIndex->m_pNext = pIndex->m_pNext->m_pNext;
        }
    }
    if(pToBeDeleted != NULL) {
        delete pToBeDeleted;
        pToBeDeleted = NULL;
    }
}

 

从尾到头打印链表:输入链表头结点,从尾到头打印每个结点的值。

注意:打印通常为只读操作,应避免修改输入链表的数据结构,传入参数应为ListNode* pHead。

可用栈实现:

void PrintListReversingly_Iteratively(ListNode* pHead) {
    std::stack<ListNode*> nodesStack;
    ListNode* pIndex = pHead;
    while(pIndex != NULL) {
        nodesStack.push(pIndex);
        pIndex = pIndex->m_pNext;
    }
    while(!nodesStack.empty()) {
        pIndex = nodesStack.top();
        printf("%d\t", pIndex->m_nValue);
        nodesStack.pop();
    }
    cout << endl;
}

 

也可用递归实现:

 

void PrintListReversingly_Recursively(ListNode* pHead) {
    if(pHead != NULL) {
        if(pHead->m_pNext != NULL)
            PrintListReversingly_Recursively(pHead->m_pNext);
        printf("%d\t", pHead->m_nValue);
    }
}

 

如果用递归实现,当链表非常长时函数调用的层级很深,可能导致函数调用栈溢出,因此使用栈实现的鲁棒性更好。

 

完整代码:

#include <iostream>
#include <stdio.h>
#include <stack>
using namespace std;

struct ListNode {
    int m_nValue;
    ListNode* m_pNext;
};

void AddToTail(ListNode** pHead, int value) {
    ListNode* pNew = new ListNode();
    pNew->m_nValue = value;
    pNew->m_pNext = NULL;
    if(*pHead == NULL) {
        *pHead = pNew;
    } else {
        ListNode* pIndex = *pHead;
        while(pIndex->m_pNext != NULL)
            pIndex = pIndex->m_pNext;
        pIndex->m_pNext = pNew;
    }
}

void RemoveNode(ListNode** pHead, int value) {
    if(pHead == NULL || *pHead == NULL)
        return;
    ListNode* pToBeDeleted = NULL;
    if((*pHead)->m_nValue == value) {
        pToBeDeleted = *pHead;
        *pHead = (*pHead)->m_pNext;
    } else {
        ListNode* pIndex = *pHead;
        while (pIndex->m_pNext != NULL && pIndex->m_pNext->m_nValue != value)
            pIndex = pIndex->m_pNext;
        if(pIndex->m_pNext != NULL && pIndex->m_pNext->m_nValue == value) {
            pToBeDeleted = pIndex->m_pNext;
            pIndex->m_pNext = pIndex->m_pNext->m_pNext;
        }
    }
    if(pToBeDeleted != NULL) {
        delete pToBeDeleted;
        pToBeDeleted = NULL;
    }
}

void PrintListReversingly_Iteratively(ListNode* pHead) {
    std::stack<ListNode*> nodesStack;
    ListNode* pIndex = pHead;
    while(pIndex != NULL) {
        nodesStack.push(pIndex);
        pIndex = pIndex->m_pNext;
    }
    while(!nodesStack.empty()) {
        pIndex = nodesStack.top();
        printf("%d\t", pIndex->m_nValue);
        nodesStack.pop();
    }
    cout << endl;
}

void PrintListReversingly_Recursively(ListNode* pHead) {
    if(pHead != NULL) {
        if(pHead->m_pNext != NULL)
            PrintListReversingly_Recursively(pHead->m_pNext);
        printf("%d\t", pHead->m_nValue);
    }
}


int main() {
    ListNode* pListHead = NULL;
    ListNode** pTest = &pListHead;
    PrintListReversingly_Recursively(pListHead);
    cout << endl;
    AddToTail(pTest, 0);
    PrintListReversingly_Recursively(pListHead);
    cout << endl;
    AddToTail(pTest, 1);
    PrintListReversingly_Recursively(pListHead);
    cout << endl;
    AddToTail(pTest, 2);
    PrintListReversingly_Recursively(pListHead);
    cout << endl;
    AddToTail(pTest, 3);
    PrintListReversingly_Recursively(pListHead);
    cout << endl;
    
    RemoveNode(pTest, 8);
    PrintListReversingly_Iteratively(pListHead);
    RemoveNode(pTest, 0);
    PrintListReversingly_Iteratively(pListHead);
    RemoveNode(pTest, 3);
    PrintListReversingly_Iteratively(pListHead);
    RemoveNode(pTest, 2);
    PrintListReversingly_Iteratively(pListHead);
    RemoveNode(pTest, 1);
    PrintListReversingly_Iteratively(pListHead);
}

 

posted @ 2017-08-24 10:55  丹尼尔奥利瓦  阅读(433)  评论(0编辑  收藏  举报