排序算法系列之八大排序算法性能比较-从实验结果分析

回顾各大排序算法的实现代码:

#include "stdafx.h"
#include <iostream>
#include <time.h>
#include <vector>
using namespace std;

template<class T>
void BubbleSort(T *x, const int N)
{
	for(int k= N-1; k>0 ;k--)
	{
		for(int i=0; i<k; i++)
		{
			if(x[i] > x[i+1])
			{
				T temp = x[i];
				x[i] = x[i+1];
				x[i+1] = temp;
			}
		}
	}
}

template<class T>
void SelectSort(T *x, const int N)//不稳定
{
	for(int i =0; i < N; i++)
	{
		int minindex = i;
		for(int j = i; j < N; j++ )
		{
			if(x[minindex] > x[j])
			{
				minindex = j;
			}
		}
		if(minindex != i)
		{
			T temp = x[i];
			x[i] = x[minindex];
			x[minindex] = temp;
		}
	}
}

template<class T>
void InsertSort(T *x,const int N)
{
	for(int i = 1; i<N; i++)
	{
		T temp = x[i];
		int j;
		for(j = i-1; j>=0 && temp<x[j] ;j--)
		{
			x[j+1] = x[j];
		}
		x[j+1] = temp;
	}
}

template<class T>
void QuickSort(T *x, int low, int high)
{
	if(high-low<=0)
		return;

	T split = x[low];
	int	splitIndex = low;
	int i = low, j = high;
	while(i < j)
	{
		while(i < j && split <=x[j])
		{
			j--;
		}

		if(i < j)
		{
			x[i] = x[j];
			x[j] = split;
			splitIndex = j;
			i++;
		}

		while(i < j && x[i]<=split)
		{
			i++;
		}

		if(i < j)
		{
			x[j] = x[i];
			x[i] = split;
			splitIndex = i;
		}
	}

	QuickSort(x,low,splitIndex-1);
	QuickSort(x,splitIndex+1,high);
}

template<class T>
void ShellSort(T *x, const int N)
{
	int d = N/2;//增量步长
	for(d;d >=1;d/=2)
	{
	//	cout<<d<<endl;
		for(int i = 0;i<d; i++)
		{
			for(int j = i; j <N-d ; j+=d)//部分插入排序
			{
				for(int m = j+d; m-d>=0 && x[m]< x[m-d]; m-=d)
				{
					T temp = x[m];
					x[m] = x[m-d];
					x[m-d] = temp;
				}
			}
		}
	}
}

template<class T>
void  HeapAdjust(T *H, int start ,int end)//已知H[start~end]中除了start之外均满足堆的定义
//本函数进行调整,使H[start~end]成为一个大顶堆
{

	T temp = H[start];
    for(int i = 2*start + 1; i<=end; i*=2)
    {
        //因为假设根结点的序号为0而不是1,所以i结点左孩子和右孩子分别为2i+1和2i+2
        if(i<end && H[i]<H[i+1])//左右孩子的比较
        {
            ++i;//i为较大的记录的下标
        }

        if(temp > H[i])//左右孩子中获胜者与父亲的比较
        {
            break;
        }
        //将孩子结点上位,则以孩子结点的位置进行下一轮的筛选
        H[start]= H[i];
        start = i;
    }

    H[start]= temp; //插入最开始不和谐的元素
}

template<class T>
void HeapSort(T *H, const int n)
{
	int N = n-1;
	//建立最大堆
	for(int i = N/2; i>=0; --i)//认为叶子节点是有序的,则只需从叶子节点的父节点开始调整
	{
		HeapAdjust(H,i,N);
	}
	for(int i = N; i>=1;--i)
	{
		T temp = H[0];
		H[0] = H[i] ;
		H[i] = temp;
		HeapAdjust(H,0,i-1);
	}
}

template<class T>
void MergeArray(T *x,int left, int mid, int right)
{
<span style="white-space:pre">	</span>T *temp = new int[right - left + 1];
<span style="white-space:pre">	</span>int i = left;
<span style="white-space:pre">	</span>int j = mid+1;
<span style="white-space:pre">	</span>int m =mid;
<span style="white-space:pre">	</span>int n = right;
<span style="white-space:pre">	</span>int k = 0;
<span style="white-space:pre">	</span>while( i <= m && j <= n)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>if(x[i] < x[j])
<span style="white-space:pre">			</span>temp[k++] = x[i++];
<span style="white-space:pre">		</span>else
<span style="white-space:pre">			</span>temp[k++] = x[j++];
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>while(i <= m)
<span style="white-space:pre">		</span>temp[k++] = x[i++];
<span style="white-space:pre">	</span>while(j <= n)
<span style="white-space:pre">		</span>temp[k++] = x[j++];

<span style="white-space:pre">	</span>for(int i = 0; i < right - left + 1; i++)
<span style="white-space:pre">	</span> x[i + left] = temp[i];
}

template<class T>
void MergeSort(T *x, int left , int right)
{
	if(left < right)
	{
		int mid = (left + right)/2;
		MergeSort(x, left, mid);
		MergeSort(x, mid+1, right);
		MergeArray(x, left, mid, right);//再将二个有序数列合并
	}
}

#define MAXBIT 3
template<class T>
void RadixSort(T *x, const int N)
{
	vector<T>Bucket[10];
	for(int b = 1; b <= MAXBIT; b++)
	{
		int basicbit = pow(10 , b);
		for(int i = 0; i < N; i++)
		{
			int index = (x[i] % basicbit) / (basicbit/10) ;
			Bucket[index].push_back(x[i]);
		}

		int i = 0;
		for(int j =0 ; j <= 9 ; j++)
		{
			for(int m = 0;  m < Bucket[j].size(); m++)
			{
				x[i++] = Bucket[j][m];
			}
		}
	}
}

定义了两个产生随机整数和随机浮点数的函数

void randomInt(int *x,const int N)
{
	srand((unsigned)time(NULL));
	for(int i = 0; i < N; i++)
	{
		x[i] = rand()%500;
	}
}

void randomFloat(float *x,const int N)
{
	srand((unsigned)time(NULL));
	for(int i = 0; i < N; i++)
	{
		x[i] = float(rand()%500)/499.0*500.0;
	}
}

以及一个打印函数

template<class T>
void print(T *x, const int N)
{
	int i;
	for(i=0; i<N; i++)
	{
		cout<<x[i]<<" ";
		if((i+1)%10==0)
			cout<<endl;
	}
	cout<<endl;
}

主函数中对各种排序函数进行调用,并输出排序时间与排序结果,当N较大时省略排序结果

int main(int argc,char **argv)
{
	int N = 1000;
	int *intA = new int[N];
	randomInt(intA , N);
	print(intA , N);

	int *A1 = new int[N],*A2 = new int[N],*A3 = new int[N],*A4= new int[N],*A5= new int[N],*A6= new int[N],*A7= new int[N],*A8= new int[N];
	for(int i = 0; i< N;i++)
	{
		A1[i] = A2[i] = A3[i] = A4[i] = A5[i] = A6[i] = A7[i] = A8[i] = intA[i];
	}

	clock_t s1,f1,s2,f2,s3,f3,s4,f4,s5,f5,s6,f6,s7,f7,s8,f8;

	s1 = clock();
	BubbleSort(A1 , N);
	f1 = clock();
	float t1 = (float)((f1 - s1)*1000.0/CLOCKS_PER_SEC);
	cout<<"BubbleSort: "<<t1<<" ms"<<endl;
	print(A1 , N);

	s2 = clock();
	SelectSort(A2 , N);
	f2 = clock();
	float t2 = (float)((f2 - s2)*1000.0/CLOCKS_PER_SEC);
	cout<<"SelectSort: "<<t2<<" ms"<<endl;
	print(A2 , N);

	s3 = clock();
	InsertSort(A3 , N);
	f3 = clock();
	float t3 = (float)((f3 - s3)*1000.0/CLOCKS_PER_SEC);
	cout<<"InsertSort: "<<t3<<" ms"<<endl;
	print(A3 , N);

	s4 = clock();
	QuickSort(A4 ,0,N-1);
	f4 = clock();
	float t4 = (float)((f4 - s4)*1000.0/CLOCKS_PER_SEC);
	cout<<"QuickSort: "<<t4<<" ms"<<endl;
	print(A4 , N);

	s5 = clock();
	ShellSort(A5, N);
	f5 = clock();
	float t5 = (float)((f5 - s5)*1000.0/CLOCKS_PER_SEC);
	cout<<"ShellSort: "<<t5<<" ms"<<endl;
	print(A5 , N);

	s6 = clock();
	HeapSort(A6 , N);
	f6 = clock();
	float t6 = (float)((f6 - s6)*1000.0/CLOCKS_PER_SEC);
	cout<<"HeapSort: "<<t6<<" ms"<<endl;
	print(A6 , N);

	s7 = clock();
	MergeSort(A7 , 0 , N-1);
	f7 = clock();
	float t7 = (float)((f7 - s7)*1000.0/CLOCKS_PER_SEC);
	cout<<"MergeSort: "<<t7<<" ms"<<endl;
	print(A7 , N);

	s8 = clock();
	RadixSort(A8 , N);
	f8 = clock();
	float t8 = (float)((f8 - s8)*1000.0/CLOCKS_PER_SEC);
	cout<<"RadixSort: "<<t8<<" ms"<<endl;
	print(A8 , N);

	//float *floatA = new float[N];
	//randomFloat(floatA , N);
	//print(floatA , N);
	//BubbleSort(floatA , N);
	//SelectSort(floatA , N);
	//InsertSort(floatA , N);
	//QuickSort(floatA ,0,N-1);
	//ShellSort(floatA , N);
	//print(floatA , N);

	return 0;
}

N=1000时,

N=10000时,

时间: 2024-11-01 16:10:21

排序算法系列之八大排序算法性能比较-从实验结果分析的相关文章

(转) 白话经典算法系列之三 希尔排序的实现(附源代码实现)

链接:http://blog.csdn.net/morewindows/article/details/6668714 希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序.因为直接插入排序在元素基本有序的情况下(接近最好情况),效率

白话经典算法系列之三 希尔排序的实现

分类: 白话经典算法系列 2011-08-08 11:41 47406人阅读 评论(46) 收藏 举报 算法shell优化c 希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的 元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序.因为 直接插入排序在元素基本有序的情况下(接近最好情

算法系列笔记1(排序)

本次主要记录一些经典的排序算法,其中包括冒泡排序.直接选择排序.插入排序.归并排序.快速排序.堆排序.希尔排序.桶排序以及计数排序和基数排序.首先会给出这些排序算法的基本思想,然后给出实现的代码,最后会给出其时间复杂度. 1:冒泡排序 思想: (1):比较相邻的前后两个元素,如果后面的数据小于前面的数据,则交换这两个数据的位置.这样经过一次遍历,最小的元素将在第0个位置,属于"冒泡". (2):重复第一步,依次将第二小-的元素排列到数组的顶端. // 交换数据的三种方法 void sw

算法基础——经典八大排序算法的Java及Python实现

概述 八大排序算法不用多说了,程序员算法基础必须要掌握的,现在总结一下加深记忆.下图是这八大排序算法的分类.名称.时间空间复杂度,以及稳定性. 代码 以下是经典八大排序算法的Java及Python代码,都是基于经典算法书籍<算法导论>里的伪代码实现的,我在关键语句部分附上了注释. 按照上图中的顺序分别介绍八大排序算法的实现(升序),前面是Java,后面是Python.Java的排序函数写在了一个类里,Python的排序函数则直接写出来了. 直接插入排序 public class InsertS

算法系列【希尔排序】篇

常见的内部排序算法有:插入排序.希尔排序.选择排序.冒泡排序.归并排序.快速排序.堆排序.基数排序等.用一张图概括: 关于时间复杂度: 1.     平方阶 (O(n2)) 排序各类简单排序:直接插入.直接选择和冒泡排序. 2.     线性对数阶 (O(nlog2n)) 排序快速排序.堆排序和归并排序: 3.     O(n1+§))排序,§ 是介于 0 和 1 之间的常数.希尔排序 4.     线性阶 (O(n)) 排序基数排序,此外还有桶.箱排序. 关于稳定性: 稳定的排序算法:冒泡排序

排序算法系列:奇偶排序算法

概述 在上一篇中我们说到了冒泡排序的原理及实现详解.冒泡排序是一种交换排序,本文还是接着上一讲,说说另一种交换排序算法--奇偶排序. 版权说明 本文链接:http://blog.csdn.net/lemon_tree12138/article/details/50605563 – Coding-Naga - 转载请注明出处 目录 概述 版权说明 目录 奇偶排序算法 算法原理 算法原理图 算法步骤 算法可行性证明 算法过程图 算法实现 算法复杂度分析 Ref GitHub源码下载 奇偶排序算法 奇

数据结构与算法系列研究九——排序算法的一些探讨

四种排序 一.实验内容     输入20个整数,分别用希尔排序.快速排序.堆排序和归并排序实现由小到大排序并输出排序结果.二.关键数据结构与核心算法   关键数据结构:由于是排序为了简单起见,选用线性表中的数组作为存储结构.   核心算法:   1.希尔排序    希尔排序的核心还是直接插入法,但是插入的位置有所讲究.要把数组分为许多段,每一段的长度除了最后的有可能不同之外,其他的都相同.该段的长度即为增量,在最后一次必须为一,此时程序变成了直接插入.每次进行隔段插入,不断地调整是的数组变得隔段

数据结构与算法系列十(排序算法概述)

1.引子 1.1.为什么要学习数据结构与算法? 有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀! 有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗? 于是问题来了:为什么还要学习数据结构与算法呢? #理由一: 面试的时候,千万不要被数据结构与算法拖了后腿 #理由二: 你真的愿意做一辈子CRUD Boy吗 #理由三: 不想写出开源框架,中间件的工程师,不是好厨子 1.2.如何系统化学习数据结构与算法?

【数据结构与算法系列之四】排序

一.排序的基本概念 1. 排序 假设含有n个记录的序列为{r1, r2, ..., rn},其相应的关键字分别为{k1, k2, ..., kn},需确定1, 2, ..., n的一种排列p1, p2, ..., pn,使其相应的关键字满足kp1<=kp2<=...<=kpn(非递减或非递增)关系,即使得序列成为一个按关键字有序的序列{rp1, rp2, ... rpn},这样的操作就称为排序. 二.排序的相关代码实现 原文地址:https://www.cnblogs.com/tom-a