比较排序与非比较排序的对比

  常见的快速排序、归并排序、堆排序、冒泡排序等属于比较排序。在排序的最终结果里,元素之间的次序依赖于它们之间的比较。每个数都必须和其他数进行比较,才能确定自己的位置。在冒泡排序之类的排序中,问题规模为n,又因为需要比较n次,所以平均时间复杂度为O(n²)。在归并排序、快速排序之类的排序中,问题规模通过分治法消减为logN次,所以时间复杂度平均O(nlogn)。比较排序的优势是,适用于各种规模的数据,也不在乎数据的分布,都能进行排序。可以说,比较排序适用于一切需要排序的情况。

计数排序、基数排序、桶排序则属于非比较排序。非比较排序是通过确定每个元素之前,应该有多少个元素来排序。针对数组arr,计算arr[i]之前有多少个元素,则唯一确定了arr[i]在排序后数组中的位置。

  非比较排序只要确定每个元素之前的已有的元素个数即可,所有一次遍历即可解决。算法时间复杂度O(n)。非比较排序时间复杂度底,但由于非比较排序需要占用空间来确定唯一位置。所以对数据规模和数据分布有一定的要求。

 

非比较排序

常见的比较排序主要有以下几种:基数排序、计数排序、桶排序。

基数排序

1、基本思想:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

2、算法实现

 package com.allSorts;

 import java.util.ArrayList;
import java.util.List; /**
* Created by Demrystv.
*/
public class Ji1Shu {
public static void main(String[] args) {
int[] a = {23,45,67,88,90,21,42,52,73,61};
System.out.println("排序前:");
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
} //基数排序
sort(a); System.out.println("");
System.out.println("排序后:");
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
} private static void sort(int[] a){ //找到最大值,看最大值有几位,从而确定要比较几次,个十百千万。。。
int max = 0;
for(int i=0;i<a.length;i++){
if(max<a[i]){
max = a[i];
}
} //找到最大值后,确定要比较几次
int times = 0;
while (max>0){
max = max/10;
times++;
} //建立从0到9十个队列
List<ArrayList> list1 = new ArrayList<>();
for(int i=0;i<10;i++){
ArrayList list2 = new ArrayList();
list1.add(list2);
} //进行times次分配和收集,不断的重复即可。
for(int i=0;i<times;i++){ //分配,按照比较的所在的位的大小将其放入list1 中,类似于数组链表中的链表
for(int j=0;j<a.length;j++){
int x = a[j] % (int)Math.pow(10,i+1) / (int)Math.pow(10,i);
ArrayList list3 = list1.get(x);
list3.add(a[j]);
list1.set(x,list3);
} //收集,然后以此从数组的从左到右,链表的从上到下进行收集,将其重新放进一个新的数组中
int count = 0 ;
for(int j=0;j<10;j++){
while (list1.get(j).size()>0){
ArrayList<Integer> list4 = list1.get(j);
a[count] = list4.get(0);
list4.remove(0);
count++;
}
}
} }
}

3、分析

  基数排序是稳定的排序算法。

  基数排序的时间复杂度为O(k*n),空间复杂度为O(m),k为数组中数值的最大位数,m为桶的的个数。

计数排序

1、基本思想是:对每一个输入的元素arr[i],确定小于 arr[i] 的元素个数,可以直接把 arr[i] 放到它输出数组中的位置上。假设有x个数小于 arr[i],所以 arr[i] 应该放在数组的第(x+1)个位置上。
2、算法实现
 package com.allSorts;

 /**
* Created by Demrystv.
*/
public class Ji4Shu {
public static void main(String[] args) {
int[] a = {23,42,53,64,63,32,13,52,97,94,26};
System.out.println("排序前:");
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
} //计数排序
sort(a); System.out.println("");
System.out.println("排序后:");
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
} private static void sort(int[] a){ if(a==null || a.length==0){
return;
} int max=0,min=0;
for(int i=0;i<a.length;i++){
max = Math.max(max,a[i]);
min = Math.min(min,a[i]);
} int[] help = new int[max-min+1];
int pos; for(int i=0;i<a.length;i++){
pos = a[i]-min;
help[pos]++;
} int index=0;
for(int i=0;i<help.length;i++){
while (help[i]>0){
a[index] = i + min;
index++;
help[i]--;
}
}
}
}

3、分析

  计数排序是稳定的排序算法。

  计数排序的时间复杂度为O(k+n),空间复杂度为O(m),k为数组中最大数与最小数差值,m为桶的的个数。

桶排序

1、基本思想是把数组 arr 划分为n个大小相同子区间(桶),每个子区间各自排序,最后合并。计数排序是桶排序的一种特殊情况,可以把计数排序当成每个桶里只有一个元素的情况。
2、算法实现
 package com.allSorts;

 import java.util.ArrayList;
import java.util.Collections; /**
* Created by Demrystv.
*/
public class Tong {
public static void main(String[] args) {
int[] a = {32,45,42,51,53,86,95,53,93,55,59};
System.out.println("排序前:");
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
} //桶排序
sort(a); System.out.println("");
System.out.println("排序后:");
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
} private static void sort(int[] a){ if(a==null || a.length==0){
return;
} int max=0,min=0;
for(int i=0;i<a.length;i++){
max = Math.max(max,a[i]);
min = Math.min(min,a[i]);
} //确定桶数,并且建立一系列的桶
int bucketNum = (max-min)/a.length+1;
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
for (int i=0;i<bucketNum;i++){
bucketArr.add(new ArrayList<Integer>());
} //将每个元素放入桶
for(int i=0;i<a.length;i++){
int num = (a[i]-min)/a.length;
bucketArr.get(num).add(a[i]);
} //对每个桶进行排序
for(int i=0;i<bucketArr.size();i++){
Collections.sort(bucketArr.get(i));
} int index = 0;
for(int i=0;i<bucketArr.size();i++){
while (bucketArr.get(i).size()>0){
a[index++] = bucketArr.get(i).get(0);
bucketArr.get(i).remove(0);
}
}
}
}

3、分析

桶排序可用于最大最小值相差较大的数据情况,。
但桶排序要求数据的分布必须均匀,否则可能导致数据都集中到一个桶中,导致桶排序失效。

数据结构与算法之非比较排序【Java】的更多相关文章

  1. 数据结构和算法(Golang实现)(25)排序算法-快速排序

    快速排序 快速排序是一种分治策略的排序算法,是由英国计算机科学家Tony Hoare发明的, 该算法被发布在1961年的Communications of the ACM 国际计算机学会月刊. 注:A ...

  2. 数据结构和算法(Golang实现)(23)排序算法-归并排序

    归并排序 归并排序是一种分治策略的排序算法.它是一种比较特殊的排序算法,通过递归地先使每个子序列有序,再将两个有序的序列进行合并成一个有序的序列. 归并排序首先由著名的现代计算机之父John_von_ ...

  3. 数据结构和算法(Golang实现)(24)排序算法-优先队列及堆排序

    优先队列及堆排序 堆排序(Heap Sort)由威尔士-加拿大计算机科学家J. W. J. Williams在1964年发明,它利用了二叉堆(A binary heap)的性质实现了排序,并证明了二叉 ...

  4. 数据结构和算法(Golang实现)(18)排序算法-前言

    排序算法 人类的发展中,我们学会了计数,比如知道小明今天打猎的兔子的数量是多少.另外一方面,我们也需要判断,今天哪个人打猎打得多,我们需要比较. 所以,排序这个很自然的需求就出来了.比如小明打了5只兔 ...

  5. 数据结构和算法(Golang实现)(19)排序算法-冒泡排序

    冒泡排序 冒泡排序是大多数人学的第一种排序算法,在面试中,也是问的最多的一种,有时候还要求手写排序代码,因为比较简单. 冒泡排序属于交换类的排序算法. 一.算法介绍 现在有一堆乱序的数,比如:5 9 ...

  6. 数据结构和算法(Golang实现)(20)排序算法-选择排序

    选择排序 选择排序,一般我们指的是简单选择排序,也可以叫直接选择排序,它不像冒泡排序一样相邻地交换元素,而是通过选择最小的元素,每轮迭代只需交换一次.虽然交换次数比冒泡少很多,但效率和冒泡排序一样的糟 ...

  7. 数据结构和算法(Golang实现)(21)排序算法-插入排序

    插入排序 插入排序,一般我们指的是简单插入排序,也可以叫直接插入排序.就是说,每次把一个数插到已经排好序的数列里面形成新的排好序的数列,以此反复. 插入排序属于插入类排序算法. 除了我以外,有些人打扑 ...

  8. 数据结构和算法(Golang实现)(22)排序算法-希尔排序

    希尔排序 1959 年一个叫Donald L. Shell (March 1, 1924 – November 2, 2015)的美国人在Communications of the ACM 国际计算机 ...

  9. Python数据结构与算法(几种排序)

    数据结构与算法(Python) 冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是 ...

随机推荐

  1. 9.3.2 map端连接-CompositeInputFormat连接类

    1.1.1         map端连接-CompositeInputFormat连接类 (1)使用CompositeInputFormat连接类需要满足三个条件: 1)两个数据集都是大的数据集,不能 ...

  2. Uncaught Error: Call to undefined function mcrypt_get_iv_size() 解决办法

    函数 mcrypt_get_iv_size 在只在(PHP 4 >= 4.0.2, PHP 5, PHP 7 < 7.2.0, PECL mcrypt >= 1.0.0) 这几个版本 ...

  3. 阿里云服务器ECS Ubuntu18.04 安装mysql

    ubuntu系统好了,这下我应该安装MySQL数据库了.在安装过程中,遇到好多坑,下面是我的安装过程. 1.在阿里云控制台,用vnc登录到服务器. 用新的用户登录到Ubuntu用户系统. 打开终端: ...

  4. pytorch之 RNN regression

    关于RNN模型参数的解释,可以参看RNN参数解释 1 import torch from torch import nn import numpy as np import matplotlib.py ...

  5. jenkins SSH发布文件 Publish over SSH

    jenkins 构建完成后需要一键发布,结构如下 A服务器 svn B服务器 jenkins C服务器 应用服务器 B从A拉取代码后打包成war,然后向C服务器拷贝war包 这里解决的就是远程拷贝问题 ...

  6. elasticsearch kibana 安装 配置

    二.Elasticsearch  配置信息 2.1  因为 Elasticsearch 可以执行脚本文件,为了安全性,默认不允许通过 root 用户启动服务.我们需要新创建用户名和用户组启动服务 2. ...

  7. Java也疯狂-分享利用ffmpeg做视频转换的工具

    朋友需要经常将视频统一转换为mp4格式,市面上的工具很多,但是转换的体积.自动化程度等都不好,于是花了一个小时给朋友写了个给予ffmpeg的批量转换工具,功能简单但是很实用,也正好给学习Java的同学 ...

  8. 小白学 Python 数据分析(7):Pandas (六)数据导入

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  9. javascript30--day03--Css Variables

     相关视频链接:https://www.bilibili.com/video/av8481988/?p=5 相关github地址:https://github.com/soyaine/JavaScri ...

  10. SQL Server等待事件—PAGEIOLATCH_EX

    什么是PAGEIOLATCH_EX等待事件? 下面我们将对PAGEIOLATCH_EX等待事件的相关资料做一个简单的归纳.整理.关于PAGEIOLATCH_EX,官方文档的简单介绍如下: PAGEIO ...