线性表 - 带头结点的循环单链表

来源:互联网 发布:淘宝家居店铺排行榜 编辑:程序博客网 时间:2024/05/04 12:35

List.h

/********************************************************************    purpose:    带头结点的循环单链表    author:     xianyun1230    QQ:         836663997    e-mail:     xianyun1230@163.com    created:    2014/02/13*********************************************************************/#include <iostream>template<typename T>class List{public:List();~List();bool push_back(const T &val);//末尾插入数据bool push_front(const T &val);//开头插入数据bool pop_front(T &val);//开头删除数据void reverse();//链表倒置bool del(const T & val);//删除所有值为val 的元素bool erase(int s, int e);//删除[s,e] 区间内容bool sort();//从小到大排列,插入排序实现int count(const T & val);//统计val 值出现的次数bool empty(){return _size == 0;}unsigned int size() const {return _size;}//返回元素个数void show() const;//遍历链表T operator[](const int n) const;private:typedef struct _Node{T data;_Node * next;}Node;Node * head, * end;//分别指向头结点、尾指针unsigned int _size;//元素数};template<typename T>List<T>::List()//默认构造函数,创建头尾结点,元素数为0{_size = 0;head = new Node;head->next = head;end = head;}template<typename T>List<T>::~List(){Node * ph = head, *pt = head->next;while(pt != head){ph = pt->next;delete pt;pt = ph;}}template<typename T>bool List<T>::push_back(const T & val){Node *temp = new Node;//temp用作新尾,next属性设为head以循环(循环链表)temp->data = val;temp->next = head;end->next = temp;end = temp;//指向新尾++_size;return true;}template<typename T>bool List<T>::push_front(const T &val){Node *temp = new Node;  temp->data = val;temp->next = head->next;head->next = temp;++_size;return true;}template<typename T>bool List<T>::pop_front(T &val){if (_size == 0)return 0;Node *temp = head->next;val = temp->data;//用于返回值head->next = temp->next;delete temp;--_size;if (_size == 0)end = head;return val;}template<typename T>void List<T>::reverse()//链表前端就地倒置{if (_size < 2)return;Node * ps = head->next;//新尾Node * pn = ps->next;//从第二个结点开始未待倒置部分Node * pnn = pn->next;//pnn标记待倒置部分while(pn != head)//到结尾会循环到head{pn->next = head->next;//pn融入已倒置部分head->next = pn;//head带领已倒置部分pn = pnn;pnn = pnn->next;//未倒置部分后移}ps->next = head;//ps指向的为已倒置部分最后一个结点,指向head保证循环end = ps;}template<typename T>bool List<T>::del(const T &val){bool deled = false;if (_size > 0){Node * pt = new Node;Node * pl = pt;Node * temp = pl;//用于释放内存pl->next = head->next;while(pl != head){if (pl->next->data == val){temp = pl->next;//存储待删位置pl->next = pl->next->next;//隔离待删结点delete temp;//释放内存--_size;deled = true;}pl = pl->next;}if (_size == 0)end = head;delete pt;}return deled;}template<typename T>bool List<T>::erase(int s, int e) //删除[s,e]区间{if (e<s || s<0 || e >= _size)return false;int num = s;Node * ps = head;while(num--)ps = ps->next;//找到下标为s 的元素的前一个元素num = e - s + 1;//释放e - s + 1 个元素Node * pe = ps->next;Node * pt = pe;while(num--){pe = pe->next;delete pt;pt = pe;}ps->next = pe;//拼接return true;}template<typename T>bool List<T>::sort()//插入排序算法{if (_size >= 2){Node * ps = head->next->next;//指向未排序区域Node *pi, *pt;head->next->next = NULL;//已排序区域(第一个结点)末尾设置NULL,以作标记while(ps != head){for (pi = head; (pi->next != NULL) && (pi->next->data <= ps->data); pi = pi->next)//查找插入位置continue;pt = ps;//存取需插入节点ps = ps->next;//未排序区后移if (pi->next != NULL)//判断是否为已排序区最大值{pt->next = pi->next;pi->next = pt;}else{pi->next = pt;pt->next = NULL;//为最大值需设置尾部NULL标记}}pt = head->next;//寻找NULL前第一个节点while(pt->next)pt = pt->next;pt->next = head;//循环}return true;}template<typename T>int List<T>::count(const T &val){int n = 0;Node * ps = head->next;while(ps != head){if (ps->data == val)++n;ps = ps->next;}return n;}template<typename T>void List<T>::show()const{Node * temp = head->next;std::cout <<"链表数据共" <<size() <<"个,内容如下:\n";while(temp != head){std::cout <<temp->data <<std::endl;temp = temp->next;}}template<typename T>T List<T>::operator[](const int n) const{if (n < 0 || n >= _size)return 0;int num = n;Node * pt = head->next;while(num--)pt = pt->next;return pt->data;}


main.cpp
#include <iostream>#include "List.h"using namespace std;int main(){List<int> link;link.push_back(31);link.push_front(23);link.push_back(12);link.push_back(32);link.push_back(76);link.push_back(93);link.push_back(34);link.show();link.reverse();link.del(12);link.show();link.sort();link.show();link.reverse();link.show();cout <<link.count(76) <<endl;cout <<"end!\n";cin.get();cin.get();return 0;}






0 0
原创粉丝点击