幾種算法的比較

 

#include<iostream>
#include<ctime>
#include<cstdlib>
#include<sys/time.h>
#define SIZE 1024*100

enum SortType
{
BUBBLESORT,
INSERTSORT,
MERGESORT,
FASTSORT
};

class SortAlgorithm
{
private:
	SortType sortType;
	int* data;//向堆空間申請內存,存放待排序數據,這裏不能是棧數據,由於待排數據量大於8Mb//
	struct timeval startTime;
	struct timeval endTime;
public:
	SortAlgorithm(){
	  srand(time(NULL));
	  this->data=new int[SIZE];
	  for(int i=0;i<SIZE;i++){  //隨機化待排數據
		data[i]=rand()%SIZE;
	  }
	}
	~SortAlgorithm(){
	  delete [] data;//釋放內存
	}
public:
	void disData();
	void sortData(SortType);
public:
	void bubbleSort();//冒泡排序
	void insertSort(int);//插入排序
	void mergeSort(int,int); //歸併排序
	void fastSort(int,int);  //快速排序
public:
	void runSort();   //開始排序 
private:
	void swap(int&,int&); //交換兩個數
	void merge(int,int,int);//歸併數組,供歸併排序調用
};

void SortAlgorithm::swap(int& a,int& b)
{
	int tmp=a;
	a=b;
	b=tmp;
}

void SortAlgorithm::merge(int start,int mid,int end)
{
	int i=start;
	int j=mid+1;
	int k=start;
	int* tmp=new int[SIZE];
	while(i!=mid+1&&j!=end+1){
		if(data[i]<=data[j]){
			tmp[k++]=data[i++];
		}
		else{
			tmp[k++]=data[j++];
		}
	}

	while(i!=mid+1){
		tmp[k++]=data[i++];
	}

	while(j!=end+1){
		tmp[k++]=data[j++];
	}

	for(int n=start;n!=end+1;n++){
		data[n]=tmp[n];
	}

	delete [] tmp;
}
void SortAlgorithm::sortData(SortType st)
{
	this->sortType=st;
}

/*
冒泡排序屬於原址排序,時間複雜度爲O(N^2),空間複雜度爲O(1),是一種穩定的排序算法
基本原理是進行N趟比較,分別比較相鄰兩個數值的大小,知足條件則交換兩個數(視排序順序
而定),每執行一趟比較一定使得相對最大數(最小數)被轉移至相對最頂端,所以N趟以後排序
完成
*/
void SortAlgorithm::bubbleSort()
{
	for(int i=0;i<SIZE;i++){// 一共須要執行SIZE趟才能所有排序徹底
		for(int j=0;j<SIZE-i-1;j++){
			if(data[j]>=data[j+1]){  // 從小到大排序
				swap(data[j],data[j+1]);
			}
		}
	}
}

/*
插入排序是一種穩定排序,時間複雜度爲O(N^2),空間複雜度爲O(1),分紅直接插入排序和二分
插入排序兩種。直接插入排序和冒泡排序在本質上是相同的,只是出發點和想法不同罷了。首先
假定數組第一個數已是排序完成,從第二個數開始依次進行比較,直到找到小於(大於)某個數的
位置則插入,不然依次日後移。
*/
void SortAlgorithm::insertSort(int size)
{
	int	tmp;
	int i;
	int j;
	for(i=1;i<size;i++){
		tmp=data[i];
		for(j=i;j>0&&(tmp<data[j-1]);j--){
			data[j]=data[j-1];
		}
		data[j]=tmp;
	}
}

/*
歸併排序是一種穩定排序,時間複雜度爲O(NlgN),空間複雜度爲O(N),由馮諾依曼提出
其實是採用分治思想而提出的一種高效率排序方法。其原理是先將待排序數組分解,而後
進行合併。即三個步驟:1、分解(devide),2、處理(conquer),3、合併(combine)
*/
void SortAlgorithm::mergeSort(int low,int high)
{
	int midNum=(low+high)/2;
	if(low<high){
		mergeSort(low,midNum);
		mergeSort(midNum+1,high);
		merge(low,midNum,high);
	}
}
/*
快速排序是一種不穩定排序方法,最差的狀況是時間複雜度爲O(N^2),指望時間複雜度爲O(NlgN)
屬於原址排序,即空間複雜度爲O(1)。經過一趟排序將要排序的數據分割成獨立的兩部分,其中
一部分的全部數據都比另一部分的全部數據都要小,而後再按此方法對這兩部分數據分別進行
快速排序,整個排序過程能夠遞歸進行,以此達到整個數據變成有序序列。
*/
void SortAlgorithm::fastSort(int low,int high)
{
	if(low>=high)	//若是搜索完成則返回
		return;
	
	int right=high;
	int left =low;
	int keyVal=this->data[high];  // 設置標誌位,凡是大於標誌位的放右邊,不然放左邊,視順序而定

	while(left<right){ //保證在子數組內
		while(left<right&&this->data[left]<=keyVal){
			left++;
		}
		this->data[right]=this->data[left];

		while(left<right&&this->data[right]>=keyVal){
			right--;
		}
		this->data[left]=this->data[right];
	}
		this->data[right]=keyVal;
		fastSort(low,left-1);
		fastSort(left+1,high);
}

void SortAlgorithm::runSort()
{
	switch(sortType){
		case BUBBLESORT: bubbleSort();			break;
		case INSERTSORT: insertSort(SIZE);		break;
		case MERGESORT : mergeSort(0,SIZE-1) ;	break;
		case FASTSORT  : fastSort(0,SIZE-1);	break;
		default: throw "not select the sort type yet";
	}
return;
}

void SortAlgorithm::disData()
{
	int cnt=0;
	for(int i=0;i<SIZE;i++){
		std::cout<<data[i]<<' ';
		cnt++;
		if(cnt%20==0)std::endl(std::cout);
	}
}
int main()
{
	SortAlgorithm sortTest;
	sortTest.sortData(MERGESORT);
	sortTest.runSort();
	sortTest.disData();
	getchar();
return 0;
}
相關文章
相關標籤/搜索