2021-12-11发表2024-11-05更新6 分钟读完 (大约970个字)0次访问C++ 单链表简单实现 不带头节点的简单实现,主要是插入、删除、反转几种类型的操作,具体看头文件就知道了。 可以使用模板、实现迭代器进行改进。 linkedlist.h12345678910111213141516171819202122232425262728293031323334#pragma onceclass ListNode {public: int data; ListNode* next; ListNode(int data = 0, ListNode* next = nullptr);};class LinkedList { ListNode* head; ListNode* tail; int length;public: LinkedList(); virtual ~LinkedList(); void PushBack(int val); void PopBack(); void PushFront(int val); void PopFront(); void Insert(int val, int pos); void RemoveByValue(int val); void RemoveByPosition(int pos); int FindByValue(int val); int FindByPosition(int pos); void Reverse(); void clean(); bool Empty(); int Size(); void Print();}; linkedlist.cpp123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456#include <iostream>#include <exception>//#include "vld.h" //visual leak detector#include "linkedlist.h"ListNode::ListNode(int data, ListNode* next) :data(data), next(next){}LinkedList::LinkedList() : head(nullptr), tail(nullptr), length(0){}LinkedList::~LinkedList(){ ListNode* node = head; ListNode* temp = nullptr; while( node != nullptr ) { temp = node; node = node->next; delete temp; }}//尾插void LinkedList::PushBack(int val){ ListNode* node = new ListNode(val); if( head == nullptr ) { head = node; } else { tail->next = node; } tail = node; length++;}//尾删void LinkedList::PopBack(){ if( head == nullptr ) return; if( head == tail ) { head = nullptr; delete tail; tail = nullptr; length--; return; } ListNode* node = head; while( node->next != tail ) { node = node->next; } delete tail; tail = nullptr; node->next = nullptr; tail = node; length--;}//头插void LinkedList::PushFront(int val){ ListNode* node = new ListNode(val); if( head == nullptr ) { head = node; tail = node; length++; return; } node->next = head; head = node; length++;}//头删void LinkedList::PopFront(){ if( head == nullptr ) return; if( head == tail ) { delete head; head = nullptr; tail = nullptr; length--; return; } ListNode* temp = head; head = head->next; delete temp; temp = nullptr; length--;}//按位置插入void LinkedList::Insert(int val, int pos){ if( pos < 0 || pos > length ) { throw std::exception("illegal position"); } if( pos == 0 ) { PushFront(val); } else if( pos == length ) { PushBack(val); } else { int _pos = 0; ListNode* node = head; ListNode* pre_node = nullptr; while( _pos < length && _pos != pos ) { pre_node = node; node = node->next; _pos++; } ListNode* insert_node = new ListNode(val); insert_node->next = node; pre_node->next = insert_node; length++; }}//按值删除void LinkedList::RemoveByValue(int val){ ListNode* node = head; ListNode* pre_node = nullptr; while( node != nullptr ) { if( node->data == val ) { if( node == head ) { node = node->next; PopFront(); } else if( node == tail ) { node = nullptr; PopBack(); } else { pre_node->next = node->next; delete node; node = nullptr; node = pre_node->next; length--; } } else { pre_node = node; node = node->next; } }}//按位置删除void LinkedList::RemoveByPosition(int pos){ if( pos < 0 || pos >= length ) { throw std::exception("illegal position"); } if( pos == 0 ) { PopFront(); } else if( pos == length - 1 ) { PopBack(); } else { int _pos = 0; ListNode* node = head; ListNode* pre_node = nullptr; while( _pos < length && _pos != pos ) { pre_node = node; node = node->next; _pos++; } pre_node->next = node->next; delete node; length--; }}//按值查找int LinkedList::FindByValue(int val){ int pos = 0; if( head == nullptr ) { return -1; } ListNode* node = head; while( node != nullptr && node->data != val ) { node = node->next; pos++; } int ret = ( pos == length ? -1 : pos ); return ret;}//按位置查找int LinkedList::FindByPosition(int pos){ if( pos < 0 || pos >= length ) { throw std::exception("illegal position"); } int _pos = 0; ListNode* node = head; while( _pos != pos ) { node = node->next; _pos++; } return node->data;}//反转链表void LinkedList::Reverse(){ if( head == nullptr || head == tail ) return; ListNode* node = head; ListNode* pre_node = nullptr; ListNode* _node = nullptr; ListNode* _pre_node = nullptr; tail = head; while( node != nullptr ) { _node = node; _pre_node = pre_node; pre_node = node; node = node->next; _node->next = _pre_node; //其实pre_node->next = _pre_node就行,完全不需要_node,有_node会更便于理解 } head = _node;}//清空void LinkedList::clean(){ ListNode* node = head; ListNode* temp = nullptr; while( node != nullptr ) { temp = node; node = node->next; delete temp; }}//判空bool LinkedList::Empty(){ return length == 0;}//长度int LinkedList::Size(){ std::cout << length << std::endl; return length;}//遍历打印节点值void LinkedList::Print(){ ListNode* node = head; while( node != nullptr ) { std::cout << node->data << " "; node = node->next; } std::cout << std::endl;}//测试int main(){ LinkedList list; /*list.PopBack(); list.PushBack(5); list.PushBack(10); list.Print(); list.PopBack(); list.Print(); list.PopBack(); list.Print(); list.PopBack(); list.Size();*/ /*list.PopFront(); list.PushFront(5); list.PushFront(10); list.Print(); list.PopFront(); list.Print(); list.PopFront(); list.Print(); list.PopFront(); list.Size();*/ /*list.PushBack(5); list.PushBack(10); list.PushBack(15); list.Print(); try { list.Insert(888, -1); } catch( std::exception& e ) { std::cout << e.what() << std::endl; } try { list.Insert(888, 4); } catch( std::exception& e ) { std::cout << e.what() << std::endl; } list.Insert(1, 0); list.Print(); list.Insert(9, 4); list.Print(); list.Insert(7, 3); list.Print(); list.Size();*/ /*list.PushBack(5); list.PushBack(10); list.PushBack(15); list.Print(); list.RemoveByValue(10); list.Print(); list.RemoveByValue(5); list.Print(); list.RemoveByValue(15); list.Print(); list.Size();*/ /*list.PushBack(5); list.PushBack(10); list.PushBack(15); list.Print(); try { list.RemoveByPosition(-1); } catch( std::exception& e ) { std::cout << e.what() << std::endl; } try { list.RemoveByPosition(3); } catch( std::exception& e ) { std::cout << e.what() << std::endl; } list.RemoveByPosition(1); list.Print(); list.RemoveByPosition(1); list.Print(); list.RemoveByPosition(0); list.Print(); list.Size();*/ /*list.PushBack(5); list.PushBack(10); list.PushBack(15); std::cout << list.FindByValue(8) << std::endl; std::cout << list.FindByValue(5) << std::endl; std::cout << list.FindByValue(15) << std::endl; std::cout << list.FindByValue(10) << std::endl;*/ /*list.PushBack(5); list.PushBack(10); list.PushBack(15); try { std::cout << list.FindByPosition(-1) << std::endl; } catch( std::exception& e ) { std::cout << e.what() << std::endl; } try { std::cout << list.FindByPosition(3) << std::endl; } catch( std::exception& e ) { std::cout << e.what() << std::endl; } std::cout << list.FindByPosition(2) << std::endl; std::cout << list.FindByPosition(0) << std::endl; std::cout << list.FindByPosition(1) << std::endl;*/ /*list.PushBack(5); list.PushBack(10); list.PushBack(15); list.PushBack(20); list.Print(); list.Reverse(); list.Print();*/ return 0;}C++ 单链表简单实现https://dullsword.github.io/2021/12/11/CPP-单链表简单实现/作者DullSword发布于2021-12-11更新于2024-11-05许可协议