基于之前做的单向链式线性表http://blog.csdn.net/shiwazone/article/details/47000191,改进下,实现了循环链表,相对应单向链表,循环链表将尾节点的指针域指向头节点,加入循环,可以让我们在查找某一个index的节点时,可以先判断一下位置和链表长度的关系,如果index处于链表的前半部分,我们可以从头节点遍历查找,如果处于后半部分,我们可以从尾节点往前查找,当然此时我们需要使用双向链表。双向链表的操作,下次给出吧!循环链表给了我们一种思路,如果我们在一个数据块中,加入一个或一些标志节点,我们可以判断我们需要的操作是在哪个区间,可以实现提高工作效率!
代码中重载了加号运算符,实现两个链表的相加。其实我们还可以有更多的操作,但是很多操作都是基于我们的插入删除操作的!所以我们在做数据结构分析的时候,我们要注意到插入和删除的通用性!
#pragma once #include <iostream> using namespace std; template<typename EleType> class CircleList { public: struct Node { EleType _data; Node* _next; Node(){ _next = nullptr; } Node(EleType data){ _data = data; _next = nullptr; } }; CircleList(); ~CircleList(); bool GetElem(EleType& e, int index = 1)const;//得到List中第index个元素,把元素的_data赋给e; bool InsertElem(const EleType e, int index = 1);//在List的第index个位置插入一个节点,节点的数据为e bool DeleteElem(EleType& e, int index = 1);//在List的第index个位置删除一个节点,删除节点的数据赋给e bool InsertHead(const EleType& e);//在头部插入数据 bool InsertTail(const EleType& e);//在尾部插入数据 bool Clear();//清空List void ShowList()const;//显示List的所有元素的数据 CircleList<EleType>* operator+(CircleList<EleType>& addList);//重载运算符 private: bool Empty()const;//判断List是否为空 CircleList<EleType>* AddList(CircleList<EleType>& addList);//加上addList的数据,相当于把addList的数据从尾部插入到原List中 //在List中查找第index个位置的节点,把该节点的地址赋给n,此处需传入指针的引用,才能保证n可以被修改,不然只能保证*n可以被修改,也就是n指向的节点可以被修改 bool Find(int index, Node*& n)const; bool CheckIndex(int index)const;//检查List是否为空,index是否合法 Node* Head;//头指针 Node* Tail;//尾指针 int Length; };
#include "CircleList.h" #include <iostream> using namespace std; template<typename EleType> bool CircleList<EleType>::CheckIndex(int index) const { if (Empty()) { cout << "Find: the List is Empty!\n"; return false; } if (index<1 || index>Length) { cout << "the index is invalid!\n"; return false; } return true; } template<typename EleType> bool CircleList<EleType>::Find(int index, Node*& n)const//index [1,Length]; { if (CheckIndex(index)) { int i = 1; Node * temp = Head; while (i < index) { temp = temp->_next; ++i; } n = temp; return true; } return false; } template<typename EleType> void CircleList<EleType>::ShowList() const { Node * temp = nullptr; if (Empty()) { cout << "The list is empty!\n"; } else { for (int i = 1; i <= Length ; ++i) { Find(i, temp); cout << temp->_data << " "; } cout << endl; } } template<typename EleType> bool CircleList<EleType>::Clear() { if (Empty()) { return true; } else { while (Length) { EleType m; DeleteElem(m); } return true; } } template<typename EleType> bool CircleList<EleType>::DeleteElem(EleType& e, int index = 1) { if (CheckIndex(index)) { Node* temp = nullptr; Node* pre_temp = nullptr; if (Find(index, temp)) { if (index == 1) { Find(index + 1, Head); } else { if (index == Length) { Find(index - 1, Tail); } else { Find(index - 1, pre_temp); pre_temp->_next = temp->_next; } } e = temp->_data; delete temp; --Length; return true; } return false; } return false; } template<typename EleType> bool CircleList<EleType>::InsertElem(const EleType e, int index) { Node *insertNode = new Node(e); if (Empty()) { if (index < 1) return false; Head = Tail = insertNode; insertNode->_next = insertNode; ++Length; return true; } if (index == 1) { insertNode->_next = Head; Head = insertNode; Tail->_next = Head; ++Length; return true; } if (index == Length + 1) { Tail->_next = insertNode; insertNode->_next = Head; Tail = insertNode; ++Length; return true; } Node *temp = nullptr; if (Find(index - 1, temp)) { insertNode->_next = temp->_next; temp->_next = insertNode; ++Length; return true; } return false; } template<typename EleType> bool CircleList<EleType>::GetElem(EleType& e, int index) const { if (CheckIndex(index)) { Node* temp = nullptr; if (Find(index, temp)) e = temp->_data; return true; } return false; } template<typename EleType> CircleList<EleType>::~CircleList() { Clear(); } template<typename EleType> CircleList<EleType>::CircleList() :Length(0), Head(nullptr), Tail(nullptr) { } template<typename EleType> bool CircleList<EleType>::Empty() const { return(Length == 0); } template<typename EleType> bool CircleList<EleType>::InsertTail(const EleType& e) { return InsertElem(e, Length + 1); } template<typename EleType> bool CircleList<EleType>::InsertHead(const EleType& e) { return InsertElem(e); } template<typename EleType> CircleList<EleType>* CircleList<EleType>::AddList(CircleList<EleType>& addList) { if (Empty()) { if (addList.Empty()) { return this; } Node* temp = addList.Head; for (int i = 1; i <= addList.Length;++i) { InsertTail(temp->_data); temp = temp->_next; } return this; } else { if (addList.Empty()) { return this; } else { Node* temp = addList.Head; for (int i = 1; i <= addList.Length; ++i) { InsertTail(temp->_data); temp = temp->_next; } return this; } } } template<typename EleType> CircleList<EleType>* CircleList<EleType>::operator+(CircleList<EleType>& addList) { return AddList(addList); }
#include "CircleList.cpp" int main() { CircleList<int> IntList1; IntList1.ShowList(); IntList1.InsertElem(155); IntList1.InsertElem(5); IntList1.InsertElem(55); IntList1.InsertElem(15); IntList1.InsertElem(99); IntList1.ShowList(); CircleList<int> IntList2; IntList2.InsertElem(11); IntList2.InsertElem(11); IntList2.InsertElem(11); IntList2.InsertElem(11); IntList2.InsertElem(11); IntList2.ShowList(); CircleList<int> *IntList3; IntList3 = IntList2 + IntList1; IntList3->ShowList(); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-09-28 02:50:11