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); }