带表头的单循环链表的实现

来源:互联网 发布:python 随机产生单词 编辑:程序博客网 时间:2024/04/28 12:40

通常在循环链表的第一个节点前附加一个特殊的节点来作为标记,这个节点称为循环链表的头结点,头结点的数据域为空域,或者按照需要设定。


在这里,我们将a1节点的地址设为first,头结点仅当作特殊标记。如果不想增加头结点,也可以实现单循环链表。

本篇的单循环链表是根据上篇《单链表的实现》上稍作修改而来,有什么好的建议请指点我!

1.头文件

#ifndef CHAIN_H#define CHAIN_H#include<iostream>//带头节点的循环链表,头结点是空表template<class T>class chainnode{  template<class T>  friend class chain;public:chainnode()   //循环链表设置默认构造函数对数据域不作初始化{next = nullptr;//初始化节点时,将该节点指向自己}~chainnode(){}void setdata(const T& dat){data = dat;}public:T getdata(){return data;}chainnode<T>* getnext(){return next;}private:T data;chainnode<T>* next;};template<class T>class chain{public:chain(){head= new chainnode < T > ; //单独开辟一个节点当作循环链表的头节点,且头结点不存储数据length = 0;head->next = head;first = nullptr;}~chain()       {chainnode<T>* temp=head->next;while (temp!=head){chainnode<T>* curr = temp;temp = temp->next;delete curr;}delete head;}public:bool isempty()   //当循环链表中只存在表头的时候,为空{return first == nullptr;}chainnode<T>* getfirst(){return first;}chainnode<T>* gethead(){return head;}void deletenode(int pos);int  getlength();void insertbefore(T dat, int pos);void insertafter(T dat, int pos);T find(int pos);private:chainnode<T>* first; //指向第一个有意义的节点chainnode<T>* head; //头结点,特殊标记int length;};template<class T>void chain<T>::insertbefore(T dat, int pos)  //在pos位置前面插入一个元素{if (pos< 0 || pos>length){std::cout << "输入的位置数错误" << endl;exit(1);}chainnode<T>* now = new chainnode < T >;now->data = dat;if (first == nullptr)  //如果循环链表只有表头,为空表{first = now;head->next = first;first->next = head;++length;}else{chainnode<T>* pp = first;for (int i = 1; i < pos - 1 && pp; ++i)pp = pp->next;if (pp){if (pos == 1){now->next = first;head->next = now;first = now;}else{now->next = pp->next;pp->next = now;}++length;}}}template<class T>void chain<T>::insertafter(T dat, int pos){if (pos < 0 || pos>length){std::cout << "输入的位置数错误" << endl;exit(1);}chainnode<T>* now = new chainnode < T >;now->data = dat;if (first == nullptr){first = now;head->next = now;first->next = head;++length;}else{chainnode<T>* pp = first;for (int i = 1; i < pos && pp; ++i)pp = pp->next;if (pp){if (pos == length){now->next = head;pp->next = now;}else{now->next = pp->next;pp->next = now;}++length;}}}template<class T>T chain<T>::find(int pos){if (first){if (pos<0 || pos>length){std::cout << "输入的位置数错误" << endl;exit(1);}chainnode<T>* curr=first;for (int i = 1; i < pos; ++i)curr = curr->next;return curr->data;}}template<class T>int chain<T>::getlength(){if (first == nullptr)return  0;chainnode<T>* current = first;int len = 0;while (current!=head){++len;current = current->next;}length = len;return len;}template<class T>void chain<T>::deletenode(int pos){if (first){if (pos<0 || pos>length){std::cout << "输入的位置数错误" << endl;exit(1);}if (pos == 1){chainnode<T>* temp = first;head->next = first->next;first = first->next;delete temp;--length;}else{chainnode<T>* tem = first;for (int i = 1; i < pos - 1 && tem; ++i) //获得pos前一个元素的地址tem = tem->next;if (tem &&tem->next)   //确保第pos个元素存在{chainnode<T>* curr = tem->next; //curr是pos位置元素的地址tem->next = curr->next;delete curr;--length;}}}}template<class T>std::ostream& operator <<(std::ostream& out, chain<T>& list) {chainnode<T>* cc = list.getfirst();for (int i = 1; i <= list.getlength(); ++i){out <<cc->getdata() << " ";cc = cc->getnext();}std::cout << std::endl;return out;}#endif

2.main文件

#include<iostream>#include"chain.h"using namespace std;int main(){chain<char> liner;liner.insertafter('A', 0);liner.insertafter('B', 1);liner.insertafter('C', 2);liner.insertafter('D', 3);liner.insertbefore('E',1);//*********测试循环链表是否完成********(liner.gethead())->setdata('H');//用H表示头结点数据,头结点数据默认为空chainnode<char>* xx = liner.getfirst();for (int i = 1; i < 10; ++i){cout << xx->getdata() << " ";xx = xx->getnext();}cout << endl;//*********这段代码目的只为测试********auto dd = liner.find(3);cout << dd << endl;cout<< liner << endl;system("pause");return 0;}


0 0
原创粉丝点击