C++单链表的建立(有头节点)

#ifndef chainWithHeader_
#define chainWithHeader_
#include<iostream>
#include<string>    //数组
#include<algorithm> //STL中的算法
#include<sstream>  //istringstream流
#include<exception>//异常处理
#include<vector>//迭代器
#include<numeric>//标准库中的数学操作函数
#include<iterator>
#include<array>
#include "chainNode.h"
using namespace std;
template<typename T>
class chainWithHeader
{
public:
	 chainWithHeader(int initialCapacity=10);
	~chainWithHeader();



	bool empty() const { return listSize == 0; }
	int size() const { return listSize; }
	void insert(int theIndex, const T& theElement);
	void insertsort();
	void output(ostream& out)const;
	void bubblingSort();
	void selectionSort();
	void rankSort();
private:
	chainNode<T>*headerNode;   //指向链表第一个节点的指针
	int listSize;
};
template<typename T>
chainWithHeader<T>::chainWithHeader(int initialCapacity)
{
	if (initialCapacity<1)
	{
		ostringstream s;
		s << "Initial capacity= " << initialCapacity << "Must be>0";
		throw illegalParameterValue(s.str());
	}
	headerNode = new chainNode<T>();
	headerNode->next= NULL;
	listSize = 0;
}
//析构函数,~chain(),思想,不断的删除首节点
template<typename T>
chainWithHeader<T>::~chainWithHeader()
{
	while (headerNode->next!= NULL)
	{
		chainNode<T>* nextNode = headerNode->next;
		delete headerNode;
		headerNode = nextNode;
	}
}
//插入函数
template<typename T>
void chainWithHeader<T>::insert(int theIndex, const T& theElement)
{
	if (theIndex == 0)//把链表头赋给自己
		headerNode->next = new chainNode<T>(theElement, headerNode->next);
	else
	{
		chainNode<T>* p =headerNode->next;
		for (int i = 0; i < theIndex - 1; i++)
			p = p->next;
		p->next = new chainNode<T>(theElement, p->next);
	}
	listSize++;
}
//输出函数
template<typename T>
void chainWithHeader<T>::output(ostream& out)const
{
	for (chainNode<T>*p = headerNode; p->next != NULL; p = p->next)
		out << p->next->element << " ";
}
//插入排序
template<typename T>
void chainWithHeader<T>::insertsort()
{
	//将链表分成两段,一段有1个元素,另一段有n-1个元素,这是基础
	chainNode<T>*p= headerNode->next->next;     //p代表第二个节点,此表从第二个节点开始
	headerNode->next->next = NULL;              //只要一个元素的表,等待插入          
	chainNode<T>*r,*q;
	while (p!= NULL)
	{
		r = p->next;                           //保存p后面还没比较的节点
		q = headerNode;                        //新表的表头,每次从表头开始找
		while (q->next != NULL&&q->next->element<= p->element)  //找到大于p的那个节点前驱
			q = q->next;
		p->next = q->next;                                 //p->next指向q->next的值
		q->next = p;               //q->next指向p处的值,相当于从p指的链表找到一个元素放入headerNode所指链表的合适位置
		p = r;                                             //进行下一次比较
	}
}
//冒泡排序(有头结点)
template<typename T>
void chainWithHeader<T>::bubblingSort()
{
	    chainNode<T>*pr, *pt,*pb,*pf,*pd;//pd表示每次要比较的尾元素,pr表示比较元素的前一个,pt表示比较元素的后一个
	    pb = headerNode;            //pb为第一个比较元素的前驱
	    pr = headerNode->next;
	    pd = NULL;
		pf = headerNode;            //pf就是为了得到每次排完序的头节点
		bool swapped = true;        //为了在已经有序的情况下能及时退出
		while (pf->next!=pd&&swapped)
		{
			pb = pf;                //pb为第一个比较元素的前驱
			pr = pf->next;
			swapped = false;        //目前为止未交换
			while (pr->next!=pd)
			{
                pt = pr->next;
				if (pr->element > pt->element)//如果两相邻的节点无序,则交换
				{
					pb->next = pt;
					pr->next = pt->next;
					pt->next = pr;
					swapped = true;
				}
				pb = pb->next;
				pr = pb->next;
			}
			pd = pr;//新的末尾
		}
}
//选择排序(有头节点)
template<typename T>
void chainWithHeader<T>::selectionSort()
{
	chainNode<T>*pd,*pf,*pe,*pa,*pmax;
	pf = headerNode;
	pd = NULL;
	bool sorted = false;                         //已经排好序之后退出循环
	while (pf->next->next!=pd&&!sorted)
	{
		pmax = pf;
		pa= pf->next;
		sorted = true;
		T temp;
		while (pa->next!= pd)
		{
			if (pmax->next->element<=pa->next->element)//找最大的元素
				pmax= pa;
			else sorted = false;
	        pe = pa;                           //记录每次查找完的最后一个元素的前驱
			pa= pa->next;
		}
		/*pb = pe->next;
		pbmax = pmax->next;

		pmax->next = pb;
		pbmax->next = pb->next;
		pb->next = pbmax->next;
		pe->next = pbmax;*/
		temp = pmax->next->element;          //和最大值和尾值交换
		pmax->next->element=pe->next->element;
		pe->next->element = temp;
        
		pd = pe->next;                             //记录尾节点,值最大
	}
}
//计数排序
template<typename T>
void chainWithHeader<T>::rankSort()
{
	//求排名
	chainNode<T>*p, *pr;
	p = headerNode->next->next;       //指向第二个元素
	int*r= new int[listSize]();   //记录排名,默认初始化为0
	int i = 1,j=0;
	while (p != NULL)
	{
		pr = headerNode->next;
		j = 0;
		while (pr!= p)
		{
            if(pr->element <= p->element)
				 ++r[i];
			else ++r[j];
			pr = pr->next;
			++j;
		}
		p = p->next;
		++i;
	}
	//根据名次排列
	chainNode<T>*pb = headerNode->next;
	int k = 0,t;
	T temp;
	while (pb != NULL)
	{
		 int i =0;
		chainNode<T>*pd = headerNode->next;
		while (k!=r[i])
		{
			pd = pd->next;
			++i;
		}
		if (k!=r[k])         //如果实际位置和名次相同,则不交换
		{
			//交换数据
			temp = pb->element;
			pb->element = pd->element;
			pd->element = temp;
            //交换名次
			t = r[i];
			r[i] = r[k];
			r[k] = t;
		}
		pb = pb->next;
		++k;
	}
	delete [] r;
}

#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值