排序算法的比较

前言

这次上机需要比较快速排序算法,堆排序以及归并排序算法的时间。由于代码都是书上的,就直接搬运过来了,上机的内容就是比较一下1000个数的排序哪一个使用的时间最短,正序,逆序,乱序分别进行比较。

需求分析

1.排序前需要有一个待排数组。
2.最大堆排序需要创建一个堆。
3.统计时间需要进行同一数组多次排序取平均值,需要申请一个空间存放。

程序功能

将输入待排数组进行从小到大排序,统计时间平均值并输出。

源代码

#include"heapsort.h"
#include"Mergesort.h"
#include"Quicksort.h"
#include<iostream>
#include<stdlib.h>
#include<random>
#include<ctime>
#include<cstring>

using namespace std;

void show(double a[],int n);
void save(double test[], double a[], int n);

void main() {
	long int n;
	int i, f,xunhuan;
	double t[] = {1,0,0,0};

		cout << "输入排序规模(1-100000):";
		cin >> n;
		cout << "\n1.正序\t2.逆序\t3.随机排序\n\n选择排序数据:";
		cin >> f;
		cout << "统计次数:";
		cin >> xunhuan;
	while (t[0]!=xunhuan) {
		default_random_engine e(time(0));
		uniform_real_distribution<double> u(1, 100);
		double *temp = new double[n];
		double * a = new double[n];
		double *test = new double[n];
		switch (f)
		{
		case 1: {for (i = 0; i < n; i++)	a[i] = i + 1; break; }
		case 2: {for (i = 0; i < n; i++)	a[i] = n - i; break; }
		case 3: {for (i = 0; i < n; i++)	a[i] = u(e); break; }
		default:
			cout << "输入错误";
			break;
		}
			//快排
			save(test, a,n);
			clock_t st1 = clock();
			QuickSort(test, n);
			clock_t	end1 = clock();
			t[1] =( t[1]+(end1 - st1)*1000.0 / CLOCKS_PER_SEC);
			//堆排
			save(test, a, n);
			clock_t st2 = clock();
			sort(test, n);
			clock_t	end2 = clock();
			t[2] = (t[2] + (end2 - st2)*1000.0 / CLOCKS_PER_SEC) ;
			//归并排序
			save(test, a, n);
			clock_t st3 = clock();
			ModMergeSort(test, temp, 0, n - 1);
			clock_t	end3 = clock();
			t[3] = (t[3] + (end3 - st3)*1000.0 / CLOCKS_PER_SEC) ;
			//
			t[0]++;
			if (t[0] == xunhuan) show(test, n);
	}
	cout << endl;
	for (int i = 0; i < 4; i++) {
		if (i == 0)
			cout << "统计次数:" << t[i] << "\t";
		else if (i == 1)
			cout << "快速排序平均时间:" << t[i] /t[0]<< "ms\t";
		else if (i == 2)
			cout << "堆排序平均时间:" << t[i]/t[0] << "ms\t";
		else if (i == 3)
			cout << "归并排序平均时间:" << t[i]/t[0] << "ms\t";
	}
	cout << endl;
	system("pause");

}
void show(double a[],int n) {
	cout << "\n排序结果:" << endl;
	for (int i = 0; i < n; i++)
		cout << a[i] << "\t";
	cout << endl;
	
}
void save(double test[],double a[], int n) {
	for (int i = 0; i < n; i++)	test[i] = a[i];
}

#pragma once
#ifndef heapsort_H
#define heapsort_H

template<class Record>
void sort(Record Array[], int n) {
	int i;
	MaxHeap<Record> max_heap = MaxHeap<Record>(Array, n, n);
	for (i = 0; i < n - 1; i++) Array[n-1-i]=max_heap.RemoveMax(); 
}

template<class T>
class MaxHeap{
private:
	T * heapArray;
	int CurrentSize;
	int MaxSize;
	void BuildHeap();//建堆
public:
	MaxHeap(T* array, int num, int max);
	virtual ~MaxHeap() {};
	bool isLeaf(int pos) const;
	int  RightChild(int pos) const;
	int  LeftChild(int pos) const;
	int  Parent(int pos) const;
	T& RemoveMax();
	void SiftDown(int left);//向下筛选
};
template<class T>
MaxHeap<T>::MaxHeap(T* Array,int num,int max) {
	CurrentSize = num;
	MaxSize = max;
	heapArray = Array;
	BuildHeap();
}
template<class T>
void MaxHeap<T>::BuildHeap()
{
	for (int i = CurrentSize / 2 - 1; i >= 0; i--)
		SiftDown(i);
}
template<class T>
bool MaxHeap<T>::isLeaf(int pos) const
{
	return (pos >= CurrentSize / 2) && (pos<CurrentSize);
}
template<class T>
int MaxHeap<T>::LeftChild(int pos) const
{
	return 2 * pos + 1;						//返回左孩子位置
}
template<class T>
int MaxHeap<T>::RightChild(int pos) const
{
	return 2 * pos + 2;						//返回右孩子位置
}
template<class T>
int MaxHeap<T>::Parent(int pos) const	//返回父节点位置
{
	return (pos - 1) / 2;
}
template<class T>
T& MaxHeap<T>::RemoveMax()
{
	if (CurrentSize == 0)
	{
		cout << "can't Delete" << endl;
		exit(1);
	}
	else
	{
		T temp = heapArray[0];					//取堆顶元素
		heapArray[0] = heapArray[CurrentSize - 1];	//堆末元素上升至堆顶
		CurrentSize--;
		SiftDown(0);							//从堆顶开始筛选
		return temp;
	}
}
template<class T>
void MaxHeap<T>::SiftDown(int left) {
	int i = left;
	int j = LeftChild(i);
	T temp = heapArray[i];
	while (j < CurrentSize) {
		if ((j < CurrentSize - 1) && (heapArray[j] < heapArray[j + 1])) j++;//寻找哪个大

		if (temp < heapArray[j]) { heapArray[i] = heapArray[j]; i = j; j = LeftChild(j); }//j为跳出标志
		else break;

	}
	heapArray[i] = temp;
}

#endif

#pragma once
#ifndef Mergesort_H
#define Mergesort_H

#define THRESHOLD 28

template<class Record>
void ModMergeSort(Record Array[],Record Temp[], int left, int right) {
	int middle;
	
	if (right - left + 1 > THRESHOLD) {
		middle = (left + right) / 2;
		ModMergeSort(Array, Temp, left, middle);
		ModMergeSort(Array, Temp, middle + 1, right);
		ModMerge(Array, Temp, left, right, middle);
	}
	else Insort(&Array[left], right - left + 1);
	
}
//优化的两个有序子序列归并
template<class Record>
void ModMerge(Record Array[],Record Temp[], int left, int right, int middle) {
	int index1, index2;
	int i, j, k;
	for (i = left; i <= middle; i++) Temp[i] = Array[i];
	for (j = 1; j <= right - middle; j++) Temp[right - j + 1] = Array[j + middle];//反过来复制
	//开始归并,取较小者
	for (index1 = left, index2 = right, k = left; k <= right; k++)//两边开始
		if (Temp[index1] <= Temp[index2])//稳定性所以等于的时候取左边
			Array[k] = Temp[index1++];
		else
			Array[k] = Temp[index2--];
}

template<class Record>
void Insort(Record Array[], int n) {
	Record Temp;
	int i, j;
	for (i = 1; i < n; i++) {
		Temp = Array[i];
		j = i - 1;
		while (j >= 0 && Temp < Array[j]) {
			Array[j + 1] = Array[j];
			j = j - 1;
		}
		Array[j + 1] = Temp;
	}
}
#endif

#pragma once
#ifndef Quicksort_H
#define Quicksort_H

#define THRESHOLD 28



template<class Record>
void QuickSort(Record *Array, int n){
	ModQuickSort(Array, 0, n - 1);
	Insort(Array, n);
}

template<class Record>
void ModQuickSort(Record Array[], int left, int right) {
	if (right - left + 1 > THRESHOLD) {
		int pivot = SelectPivot(left, right);
		swap(Array, pivot, right);
		pivot = Partition(Array, left, right);
		ModQuickSort(Array, left, pivot);
		ModQuickSort(Array, pivot + 1, right);
	}
}
template<class Record>
void swap(Record Array[],int p,int right) {
	Record temp = Array[p];
	Array[p] = Array[right];
	Array[right] = temp;
}
int SelectPivot(int left,int right) {
	return (left + right) / 2;
}

template<class Record>
int Partition(Record Array[],int left,int right) {//分割函数
	int l = left;
	int r = right;
	Record Temp = Array[r];
	while (l != r) {
		while (Array[l] <= Temp&&l < r) l++;
		if (l < r) {
			Array[r] = Array[l];
			r--;
		}
		while (Array[r] >= Temp&&r > l)r--;
		if (r > l) {
			Array[l] = Array[r];
			l++;
		}
	}//最终l=r
	Array[l] = Temp;
	return l;//返回分界值
}


结语

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值