zoukankan      html  css  js  c++  java
  • 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	", 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	", 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	", 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	", 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);
    }
  • 相关阅读:
    Linux上传下载文件(rz/sz)
    注册页面(函数调用,数组,对象,for,innerHTML)
    课程表(点击事件,for)
    winform中固定界面大小的方法
    VS常用快捷键
    Python的标准输出
    Spring注解驱动第二讲--@ComponentScan扫描介绍
    Spring注解驱动第一讲--Spring环境搭建
    通用目标检测
    通用目标检测-发展趋势
  • 原文地址:https://www.cnblogs.com/RDaneelOlivaw/p/7418160.html
Copyright © 2011-2022 走看看