各类排序方法以及效率对比,以万为计数单位

#include "stdio.h"
#include <time.h>
#include <Windows.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
//直接插入排序 - length(序列成员的个数)
void SelectSort(int a[], int length)                                           
{
int temp = 0; 
int SerialNumTab = 0;
int NoSerialNumHead = 0;
// SerialNumRear(无序列的头部标号)  SerialNumPenult(有序列的元素标号)  temp(交换数中介)
for (NoSerialNumHead = 1; NoSerialNumHead < length; NoSerialNumHead++)                                
{
if (a[NoSerialNumHead] < a[NoSerialNumHead-1])
{
// 从有序列尾部开始向前查找出小于无序列头部的数并插入
temp = a[NoSerialNumHead];
for (SerialNumTab = NoSerialNumHead - 1; SerialNumTab >= 0 && temp < a[SerialNumTab]; --SerialNumTab)            
{
a[SerialNumTab+1] = a[SerialNumTab];
a[SerialNumTab] = temp;
}
}
}
}


// shell插入排序 - length(序列成员的个数)   
void ShellSort(int a[], int length)                               
{
int temp = 0;
int SonSerialNum = 0;
int LastSerialNumTab = 0;
int FrontSerialNumTab = 0; 
// SonSerialNum(子序列元素个数)   LastSerialNumTab(最末尾子序列元素标号)  FrontSerialNumTab(前一子序列元素标号)  temp(交换数中介)
for(SonSerialNum = length/2; SonSerialNum > 0; SonSerialNum /= 2)                                          
{
for (LastSerialNumTab = SonSerialNum; LastSerialNumTab < length; ++LastSerialNumTab)                                                             
{
// 将子序列间对应标号的所有数按小到大排序      
for (FrontSerialNumTab = (LastSerialNumTab - SonSerialNum); 
FrontSerialNumTab > 0 && a[FrontSerialNumTab] > a[FrontSerialNumTab + SonSerialNum];
FrontSerialNumTab -= SonSerialNum)                                
{
temp = a[FrontSerialNumTab];
a[FrontSerialNumTab] = a[FrontSerialNumTab + SonSerialNum];
a[FrontSerialNumTab + SonSerialNum] = temp;
}
}
}
}


// 冒泡排序 - length(序列成员的个数) 
void BubbleSort(int a[], int length)                                    
{
int temp = 0;    
int SerialNumRear = 0;
int NoSerialNumTab = 0;          
// SerialNumRear(有序列的尾部标号) NoSerialNumTab(无序列的元素标号)  temp(交换数中介)
for (SerialNumRear = 0; SerialNumRear < length; ++SerialNumRear)
{
// 从无序列尾部开始向前查找出最小的数排于有序列尾部
for (NoSerialNumTab = length - 1; NoSerialNumTab >= SerialNumRear; --NoSerialNumTab)              
{
if (a[NoSerialNumTab] < a[NoSerialNumTab - 1])                                            
{
temp = a[NoSerialNumTab];
a[NoSerialNumTab] = a[NoSerialNumTab - 1];
a[NoSerialNumTab - 1] = temp;
}
}
}
}


// 快速排序 - first(序列起始位),end(序列最末位) 
void QuickSort(int a[], int first, int end)
{
//low(低位标号), high(高位标号)
int low = first;
int high = end;
    int temp = a[first];                  
if (first >= end)
{
return;
}
while (low < high)
{
while(low < high && a[high] >= temp)
{
--high;
}
a[low] = a[high];
while(low < high && a[low] <= temp)
{
++low;  
}
a[high] = a[low];
}
a[low] = temp;
if (first < low - 1)
{
QuickSort(a, first, low - 1);
}
if (end > low+1)
{
QuickSort(a, low + 1, end);
}
}


/* 堆排序 - start - Num(序列元素个数)    Crunode(根结点标号) */
void InitialiTree(int a[], int Crunode, int Num)
{
// left(左结点),right(右结点),large(最大数标号),temp(交换数中介)  
int temp = 0;
int large = 0;
int left = 2 * Crunode + 1;                                                         
int right =2 * Crunode + 2;
// 当数组的总数Num都小于左结点时,表示没有左子树了。
if (Num < left)                                  
{
return;
}
large = left; 


// 当存在右子树,并且右结点的数比左结点的数大时,large为右结点
if (right <= Num && a[right] > a[left])              
{
large=right;
}
if (a[Crunode] < a[large])
{
temp = a[Crunode];
a[Crunode] = a[large];
a[large] = temp;
InitialiTree(a, large, Num);
}
}
// 创建堆 length(序列成员个数)
void CreatTree(int a[],int lenght)                  
{
// Crunode(根结点标号)
for (int Crunode = lenght / 2 - 1; Crunode >= 0; --Crunode)             
{
InitialiTree(a, Crunode, lenght - 1);
}
}
// 堆排序  
void HeapSort(int a[], int lenght)                               
{
// LastTab(尾部标号) temp(交换数中介)
int temp = 0;   
int LastTab = 0;  


// 创建完全二叉树
CreatTree(a, lenght);   


// 根结点与尾部数交换
for (LastTab = lenght - 1; LastTab > 0; --LastTab)   
{
temp = a[0];
a[0] = a[LastTab];
a[LastTab] = temp;


// 重新构建完全二叉树  
InitialiTree(a, 0, LastTab - 1);                    
}
}
/* 堆排序 - end */


// 100内计数排序(计数排序适合知道最大数信息下使用,比如说成绩排序(100分值)) - length(序列成员个数) 
void Counting_Sort(int a[], int length)
{       
// 将c数组全部赋值为0
int c[100];
memset(c, 0, sizeof(int) * 100);


// 遍历a数组将a数组中的数变为c数组的标号
for (int j = 0; j < length; j++)            
{
++c[a[j]];
}


// 遍历c数组
int aNum = 0;  
for(int n = 0; n < 100; ++n)                
{
if (c[n] != 0)
{
for (c[n]; c[n] > 0; --c[n])       
{
a[aNum++] = n;
}
}
}
}


// 100内基数排序(限制于位数)
void BucketSort(int a[], int length)
{
// GeiWeiNum(个位标数) ShiWeiNum(十位标数) aNum(a数组个数) 
int GeWeiNum = 0;
int ShiWeiNum = 0;
int temp[10][10];
memset(temp, 0, sizeof(int) * 10 * 10);


for (int i = 0; i < length; ++i)
{
GeWeiNum = a[i] % 10;
ShiWeiNum = a[i] / 10;
++temp[ShiWeiNum][GeWeiNum];
}


int aNum = 0;
for (int j = 0; j < 10; ++j)
{
for (int k = 0; k < 10; ++k)
{
if (temp[j][k] != 0)
{
for (temp[j][k]; temp[j][k] > 0; --temp[j][k])
{
a[aNum++] = j * 10 + k;
}
}
}
}
}


void Swap(int a[],int b[],int length)
{
for (int i = 0; i <length; ++i)
{
b[i] = a[i];
}
}


int main() 
{
double time;
int num[10000], cz[10000];
LARGE_INTEGER m_liPerfFreq;
LARGE_INTEGER m_liPerfStart;
LARGE_INTEGER m_liPerfNow;
srand(0);
for(int i = 0; i < 10000; ++i)
{
num[i] = (int)(rand() % 100);
}


Swap(num, cz, 10000);
QueryPerformanceFrequency(&m_liPerfFreq); 
QueryPerformanceCounter(&m_liPerfStart);
QuickSort(num, 0, 9999);
QueryPerformanceCounter(&m_liPerfNow);
time = (double)(m_liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000 / (double)m_liPerfFreq.QuadPart;
cout<<"用(外排序)快速排序:"<<"执行时间:"<<time<<ends<<"效率很高,在要求效率时可使用"<<endl;


Swap(cz, num, 10000);
QueryPerformanceCounter(&m_liPerfStart);
HeapSort(num, 10000);
QueryPerformanceCounter(&m_liPerfNow);
time = (double)(m_liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000 / (double)m_liPerfFreq.QuadPart;
cout<<"用(外排序)堆排序:"<<"执行时间:"<<time<<ends<<"效率高,但比快排、shell排低" <<endl;


Swap(cz, num, 10000);
QueryPerformanceCounter(&m_liPerfStart);
SelectSort(num, 10000);
QueryPerformanceCounter(&m_liPerfNow);
time = (double)(m_liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000 / (double)m_liPerfFreq.QuadPart;
cout<<"用(内排序)直接排序:"<<"执行时间:"<<time<<ends<<"效率低,在不要求效率时可使用"<<endl;


Swap(cz, num, 10000);
QueryPerformanceCounter(&m_liPerfStart);
ShellSort(num, 10000);
QueryPerformanceCounter(&m_liPerfNow);
time=(double)(m_liPerfNow.QuadPart - m_liPerfStart.QuadPart)* 1000/(double)m_liPerfFreq.QuadPart;
cout<<"用(内排序)shell排序:"<<"执行时间:"<<time<<ends<<"效率高,比快排低,在求效率时可使用"<<endl;


Swap(cz, num, 10000);
QueryPerformanceCounter(&m_liPerfStart);
BubbleSort(num, 10000);
QueryPerformanceCounter(&m_liPerfNow);
time = (double)(m_liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000 / (double)m_liPerfFreq.QuadPart;
cout<<"用(内排序)冒泡排序:"<<"执行时间:"<<time<<ends<<"效率最低,不求效率时使用"<<endl;


Swap(cz, num, 10000);
QueryPerformanceCounter(&m_liPerfStart);
Counting_Sort(num, 10000);
QueryPerformanceCounter(&m_liPerfNow);
time = (double)(m_liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000 / (double)m_liPerfFreq.QuadPart;
cout<<"100内计数排序:"<<"执行时间:"<<time<<ends<<"视情况而定,效率高,但是必须知道最大范围"<<endl;


Swap(cz, num, 10000);
QueryPerformanceCounter(&m_liPerfStart);
BucketSort(num, 10000);
QueryPerformanceCounter(&m_liPerfNow);
time = (double)(m_liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000 / (double)m_liPerfFreq.QuadPart;
cout<<"100内基数排序:"<<"执行时间:"<<time<<ends<<"视情况而定,效率比计数稍低,但是必须知道最大范围"<<endl;
Swap(cz, num, 10000);
system("pause");
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值