链表排序实现

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





你可能感兴趣的:(排序,链表)