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

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






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值