//Filename: List.h
#ifndef LIST_H_INCLUDED
#define LIST_H_INCLUDED
template<class T>
struct Node{
T value;
Node<T> *link;
Node(Node<T> *l =NULL){
link = l;
}
Node(const T &x, Node<T> *l=NULL){
value = x;
link = l;
}
};
//List类及所需函数定义
template<class T>
class List{
public:
List(){first =new Node<T>;};
~List(){
//cout<<"析构ing"<<endl;
makeEmpty();
};
void copy(List<T> &L) //拷贝链表,全拷贝
{
makeEmpty();
T value;
Node<T> *current = first;
Node<T> *currentofL = L.first;
while(currentofL->link!= NULL)
{
value = currentofL->link->value;
current->link = new Node<T>(value);
currentofL = currentofL->link;
current = current->link;
}
current->link = NULL;
}
void makeEmpty() //清空链表
{
Node<T> *current = first;
while(current->link!=NULL)
{
Node<T> *temp = current->link;
current->link = temp->link;
delete temp;
}
}
int GetLength()//得到链表的长度
{
int count = 0;
Node<T> *current = first->link;
while(current!=NULL)
{
count++;
current = current->link;
}
return count;
}
Node<T> *GetNode(int n) //返回第n个节点,n从一开始计数
{
Node<T> *current = first;
if(n<=0)
{
cerr<<"所查找节点值太小!"<<endl;
return NULL;
}
for(int i =0;i<n;i++)
{
current= current->link;
if(current ==NULL)
{
cout<<"所查找节点超出链表总长度!"<<endl;
return NULL;
}
}
return current;
}
Node<T> *GetTail()//找到链表尾部
{
Node<T> *current = first;
while(current->link!=NULL)
current = current->link;
return current;
}
void RemoveTail() //去掉最后一个节点
{
Node<T> *pre = NULL ;
Node<T> *current = first;
if(current->link==NULL)
{
cerr<<"There is no item in the list"<<endl;
return;
}
while(current->link != NULL)//current->link若为NULL,则current为尾部
{
pre = current;
current = current->link;
}
delete current;
pre->link = NULL;
}
void AddToTail(const T &x)//链表尾部添加
{
Node<T> *newNode = new Node<T>(x);
Node<T> *tail = GetTail();
tail->link = newNode;
}
void InsertbySort(const T &x)//按顺序插入,在按顺序重构链表用到
{
Node<T> *current = first;
Node<T> *newNode = new Node<T>(x);
while(current->link != NULL)
{
if(x > current->link->value)
current = current->link;
else
{
newNode->link = current->link;
current->link = newNode;
return;
}
}
//插入到了尾部
current->link =newNode;
newNode->link = NULL;
}
void ReConstructSort() //构造新的链表形成排序,此方法空间要求较大
{
int length = GetLength();
List<T> newList;
for(int i =1;i<=length;i++)
{
Node<T> *tempNode = GetNode(i);
T temp = tempNode->value;
newList.InsertbySort(temp);
}
copy(newList); //注意是全拷贝
}
void SelectSort()//选择排序,每次选择未排序部分的最小值交换到前面
{
if(first->link == NULL) return; //链表为空
if(first->link->link ==NULL) return; //只有一个节点
Node<T> *pSorting = first->link; //记录正在排序的点
while(pSorting!=NULL)
{
Node<T> *pTemp = pSorting->link; //从pSorting开始往后遍历
Node<T> *pMin = pSorting; //暂存从pSorting开始的最小的点
while(pTemp!=NULL)
{
if(pTemp->value < pMin->value)
pMin = pTemp;
pTemp = pTemp->link;
}
//进行交换
T temp = pSorting->value;
pSorting->value = pMin->value;
pMin->value = temp;
//排序下一个点
pSorting = pSorting->link;
}
}
void InsertSort()//插入排序
{
if(first->link == NULL) return; //链表为空
if(first->link->link ==NULL) return; //只有一个节点,返回
Node<T> *pInsert = first->link->link; //插入的点
Node<T> *pSorting = first->link; //前面到pSorting已经有序,则pSoring->link是下一个需要排序的点
while(pInsert != NULL)
{
Node<T> *pTemp = first->link;
Node<T> *pPre = first;
while(pTemp!=pInsert && pTemp->value <= pInsert->value)
{
pTemp = pTemp->link;
pPre = pPre->link;
}
if(pTemp == pInsert) //所插入的值比前面的都大,则无需调整
pSorting= pInsert;
else
{
pSorting->link = pInsert->link; //pSorted->link将是下一个需要排序的点
pPre->link = pInsert;
pInsert->link = pTemp;
}
pInsert = pSorting->link;
}
}
void BubbleSort()//冒泡排序,每次将最大的交换到后面
{
if(first->link == NULL) return; //链表为空
if(first->link->link ==NULL) return; //只有一个节点,返回
bool isChange = true;
Node<T> *pStop = NULL;
while(isChange && pStop!= first->link)
{
isChange = false;
Node<T> *pTemp = first->link;
while(pTemp->link!= pStop)
{
if(pTemp->value > pTemp->link->value)
{
swap(pTemp->value,pTemp->link->value);
isChange = true;
}
pTemp = pTemp->link;
}
pStop = pTemp;
}
}
void QuickSort() //快速排序
{
if(first->link == NULL) return;
if(first->link->link ==NULL) return ;
qSort(first->link,NULL);
}
void qSort(Node<T> *left, Node<T> *right) //快速排序递归
{
//排序范围为[left,right) //注意左闭右开,即右边界并不参与排序
if(left != right && left->link!=right)
{
Node<T> *mid = partition(left,right);
qSort(left,mid);
qSort(mid->link,right);
}
}
Node<T>* partition(Node<T> *left, Node<T> *right) //快排左右分割
{
//直接选择left作为分割点
T key = left->value;
Node<T> *loc = left;
for(Node<T> *i = left->link;i!=right;i = i->link)
{
if(i->value < key) //每次遇到比key小的就交换到前面,loc->link就是要交换到的位置
{
loc = loc->link;
swap(loc->value,i->value);
}
}
swap(loc->value,left->value); //将临界值换到中间
return loc;
}
private:
Node<T> *first; //头结点,并不存数值
};
#endif // LIST_H_INCLUDED
//Filename:TestOfSort.cpp
#include <iostream>
#include <time.h>
#include "List.h"
using namespace std;
//链表排序功能演示
void TestOfSort()
{
cout<<"----Test Of Sort----"<<endl;
List<int> l;
//srand((unsigned)time(0));//初始化随机数种子
char c = 'n';
while(c=='n')
{
l.makeEmpty();
for(int i = 0;i<10;i++) //链表添加20个随机数
{
int temp = rand()%100;
l.AddToTail(temp); //每次都加入到尾部
}
cout<<"\nBefore Sorting."<<endl;
for(int i = 1;i<=l.GetLength();i++)
{
cout<<l.GetNode(i)->value<<" ";
}
cout<<"\n选择排序方式(1.选择排序;2.插入排序;3.重构排序;4.冒泡排序;5.快速排序):";
int choose;
cin>>choose;
switch(choose)
{
case 1: l.SelectSort();break;
case 2: l.InsertSort();break;
case 3: l.ReConstructSort();break;
case 4: l.BubbleSort();break;
case 5: l.QuickSort();break;
default: l.SelectSort();break;
}
cout<<"After Sorting."<<endl;
for(int i = 1;i<=l.GetLength();i++)
{
cout<<l.GetNode(i)->value<<" ";
}
cout<<endl;
cout<<"是否退出(y or n):";
cin>>c;
}
};
//Filename: main.cpp
#include <iostream>
#include <time.h>
#include "List.h"
using namespace std;
void TestOfSort();
int main()
{
TestOfSort();
system("pause");
return 0;
}