#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
C++单链表的建立(有头节点)
最新推荐文章于 2024-09-18 22:30:23 发布