前言
这次上机需要比较快速排序算法,堆排序以及归并排序算法的时间。由于代码都是书上的,就直接搬运过来了,上机的内容就是比较一下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;//返回分界值
}