【第21期】观点:人工智能到底用 GPU?还是用 FPGA?

算法系列(五)排序算法下篇--如何超越排序算法下界

原创 2016年06月01日 23:57:56

概述

算法系列(四)排序算法中篇--归并排序和快速排序一文中,我们介绍了归并排序和快速排序,最坏的情况下,最快的排序算法的时间复杂度是O(nlogn),是否有更好的算法呢?到目前为止,没有特殊的规则,O(nlogn)已经是最好的排序算法了,也就是说通用排序算法的时间复杂度下界就是O(nlogn)。如果限定一些规则,是可以打破这个下界的。下面说一下尽在O(n)时间内就能实现对数组排序的算法。

基于排序的规则

基于什么样的规则才能突破排序的下界呢?我们需要分析一下排序消耗的时间。排序需要遍历,比较,交换。能否省略其中的一些步骤呢?这就是要定义的规则,通过规则减少排序步骤。下面举一个最简单的例子。
一组待排序的元素仅有1和2,没有其它值,对这组数进行排序。
输入A0,A1,A2,A3......An-1,Ai为1或者2
排序步骤
1、令k=0
2、令i从0到n-1依次取值,如果A[i]=1,k自增1
3、令i从0到k-1依次取值,将A[i]赋值为1
4、令i从k到n-1依次取值,将A[i]赋值为2
这样我们完成了排序,花费的时间为O(n)
之前我们所说的算法都是通过比较元素对来确定顺序,那种排序叫做比较排序。凡是比较排序,通用下界为O(nlogn)
刚才所说的简单例子,是一个简单计数排序。下面详细说明一下

使用基数排序超越排序下界

简单例子每个元素仅有两种可能的取值,扩展一下,如果每个元素有m个不同取值,只要取值是m个连续整数之内的整数,算法是通用的。
首先,通过计算出有多少个元素的排序关键字等于某个值,随后就能就算出有多少个元素的排序关键字小于每个可能的排序。

基本思想

计数排序的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定)。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。

计数排序算法详细描述

该算法需要三个基本方法

COUNT-KEY-EQUAL(A,n,m)

输入 A 一个数组,
         n 数组A中的元素个数
         m数组A中元素的取值范围
输出一个数组equal[0......m],是equal[j]等于数组A中元素值为j的元素个数
1、创建一个新数组equal[0......m]
2、令equal数组每个元素都为0
3、i从0到n-1依次取值,每次将equal[A[i]]的值自增1
4、返回equal

COUNT-KEY-LESS(equal,m)

输入值 COUNT-KEY-EQUAL方法对应的值equal,m
输出一个数组less[0......m],less[j]=equal[0]+equal[1]+......+equal[j-1]
1、创建一个新数组less[0...m]
2、令less[0]=0
3、j从1取到m,less[j]=less[j-1]+equal[j-1](这是普通的迭代算法)
4、返回less

REARRANGE(A,less,n,m)

输入 COUNT-KEY-EQUAL COUNT-KEY-LESS方法对应的A,less,n,m
输出 数组B,B中包含A中所有元素,并且已经排好序
1、创建新数组B[0...n-1],next[0.....m]
2、j从0到m依次取值
令next[j]=less[j]+1
3、令i从0到n-1依次取值
key=A[i];index=next[key],B[index]=A[i],next[key]++
4、返回数组B

代码实现

进行了逻辑整合,基本思路相同
package com.algorithm.sort;

/**
 * 计数排序
 * 
 * @author chao
 *
 */
public class CountSort {

	public static void main(String[] args) {
		int[] num = { 1, 1 };
		sort(num);
		for (int i = 0; i < num.length; i++)
			System.out.print(num[i] + " ");
	}

	/**
	 * 计数排序
	 * 
	 * @param num
	 */
	public static void sort(int[] num) {
		int len = num.length;
		int[] orign = new int[len];
		int max = 0;// 我们只对正整数排序
		for (int i = 0; i < len; i++) {
			orign[i] = num[i];
			if (num[i] > max) {
				max = num[i];
			}
		}
		max = max + 1;
		int[] count = new int[max];
		for (int i = 0; i < max; i++) {
			count[i] = 0;
		}
		for (int i = 0; i < len; i++) {
			count[num[i]]++;
		}
		int t1, t2;
		t1 = count[1];
		count[0] = count[1] = 0;
		for (int i = 2; i < max; i++) {
			t2 = count[i];
			count[i] = t1 + count[i - 1];
			t1 = t2;
		}
		int key, index;
		for (int i = 0; i < len; i++) {
			key = orign[i];
			index = count[key];
			num[index] = orign[i];
			count[key]++;
		}
	}
}

复杂度分析

计数排序的复杂性为O(n),但是有空间代价,如果最大数很大的话,空间代价非常大。
还有一种排序叫做基数排序,是基于计数排序的,有约束条件,时间复杂度为O(n)
桶排序,基数排序跟计数排序类似,不再详细说明,堆排序(很常用,在树形算法分析中会再说明)
代码实现可以看github,地址https://github.com/robertjc/simplealgorithm
github代码也在不断完善中,有些地方可能有问题,还请多指教

欢迎扫描二维码,关注公众账号






版权声明:本文为robert原创文章,未经博主允许不得转载。博客地址http://blog.csdn.net/robertcpp 举报

相关文章推荐

白话经典算法系列之五 归并排序的实现

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第...

【排序算法】快速排序超级总结

快速排序 一、介绍   快速排序和合并排序有点类似,两者可以相互比较。快速排序也是像合并排序那样将整个序列分成两段分别进行排序。但是快速排序没有合并排序的合并过程。      该算法是1960 ...

排序算法总结

转自:http://www.cnblogs.com/longyi1234/archive/2010/03/22/1691904.html 按平均时间将排序分为四类: (1)平方阶(O(n2))...

表格排序

表格排序 利用json数据格式填充表格中的数据 data.js var table=document.getElementById(“table”); var tableTitle={ li...

数据可视化基本图表

数据可视化:基本图表 作者: 阮一峰 日期: 2014年11月29日 "数据可视化"可以帮助用户理解数据,一直是热门方向。 图表是"数据...

JavaScript实现表格的排序

利用JS实现表格排序,依赖于JS数组中Array对象的sort方法 首先介绍一下sort()方法: 1.定义和用法: sort()方法用于对数组元素的排序 2.语法: arrayObject...

常见的数据分析图表类型以及各自的使用场景!

1.柱状图 适用场景:适用场合是二维数据集(每个数据点包括两个值x和y),但只有一个维度需要比较,用于显示一段时间内的数据变化或显示各项之间的比较情况。 优势:柱状图利用柱子的高度,反映数...

基于QSortFilterProxyModel实现表格数据查询排序框架

基于QSortFilterProxyModel实现表格数据查询排序框架表格是用户界面中最常用的控件,Qt的QTableView采用Model-View模式实现了强大的表格数据展现功能,视图与模型分离,...

统计分析基础 (一) 数据统计与图表

统计学是在数据分析的基础上,自17世纪中叶产生并逐步发展起来的一门学科。它是研究如何测定、收集、整理、归纳和分析反映数据,以便给出正确消息的科学。统计广泛地应用在各门学科,从自然科学、社会科学到人文学...

02.手把手教你 .Net EasyUI DataGrid(数据表格排序)

在上一篇我已经介绍了从数据库加载数据到DataGrid的方法,那么今天的这篇博客是介绍,怎样排序你加载的数据。 (1)DataGrid的排序相关的属性,表2-1 sortable ...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)