(请观看本人博文——《详解 普通数组 —— Arrays类 与 浅克隆》

在本人《数据结构与算法》专栏的讲解中,本人讲解了如何去实现数组的八大排序。

但是,在讲解的过程中,我们能够发现:这些几乎都和指针相关

同学们可能就会和本人一样,想到了Java中不存在指针的概念

那么,该如何去实现呢?

本人在这里要提出的一点是:

虽然Java不存在指针,但是,Java处处都是指针。

这句话可能在本人的《Java SE》专栏的前期博文中大家经常能够看到。

那么,现在,本人就来讲解下在Java中,这八大排序该如何实现:


冒泡排序

时间复杂度

O(n^2)

基本原理

每一个数与它后面的数相比较,最终每一轮排完都会将未排序中最大(或最小)的数排在适当的位置

动态演示



代码实现

package aboutArraySort;

import java.util.Arrays;

public class BubbleSort {

	public static void main(String[] args) {
int[] array = {37, 59, 43, -98, -17, 0};
sort(array);
System.out.println(Arrays.toString(array));
} public static void sort(int[] array) {
for (int i = array.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
if (array[j] > array[j+1]) {
swapValue(array, j, j+1);
}
}
}
} private static void swapValue(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
} }

那么,本人来展示下运行结果


选择排序

时间复杂度

O(n^2)

基本原理

未排序序列的第一个数和后面的所有数相比,

这样一轮下来,最大(或最小)的数就排到了相应的位置

经过最多(array.length - 1)轮后,整个数组就排好了序

动态演示



代码实现

package aboutArraySort;

import java.util.Arrays;

public class SelectionSort {

	public static void main(String[] args) {
int[] array = {37, 59, 43, -98, -17, 0};
sort(array);
System.out.println(Arrays.toString(array));
} public static void sort(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = i+1; j < array.length; j++) {
if (array[i] > array[j]) {
swapValue(array, i, j);
}
}
}
} private static void swapValue(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
} }

那么,本人来展示下运行结果


插入排序

时间复杂度

O(n^2)

基本原理

首先将原始数组分成两个数组容器(可通过下标来)

将原始数组的第一个数放在1号容器中,其余放在2号容器中

从2号容器中逐个取出,插在1号容器的适当位置

动态演示

代码实现

package aboutArraySort;

import java.util.Arrays;

public class InsertionSort {

	public static void main(String[] args) {
int[] array = {37, 59, 43, -98, -17, 0};
sort(array);
System.out.println(Arrays.toString(array));
} public static void sort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i; j > 0; j--) {
if (array[j-1] > array[j]) {
swapValue(array, j-1, j);
}
}
}
} private static void swapValue(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
} }

那么,本人来展示下运行结果


希尔排序

时间复杂度

O(n^1.3)

基本原理

先将原数组中的数据按照增量step分组

分出来的组按照插入排序进行排序

之后再对每个小组按照增量step/2分组

再对每个小组进行插入排序。

如此类推,直到增量step=1时,整个数组就排好序了

那么,看了上面的基本原理,我们就能知道 :

增量step的选取十分关键

所以,在这里,本人就用了克努特序列来计算增量step。

所谓克努特序列

就是按照:num = num*3 + 1的顺序排列的序列

例:1, 4, 13, 40, 121, 364 ... ...

由数学推导可得:用这种序列来进行希尔排序,效率极高

动态演示

代码实现

package aboutArraySort;

import java.util.Arrays;

public class ShellSort {

	public static void main(String[] args) {
int[] array = {37, 59, 43, -98, -17, 0};
sort(array);
System.out.println(Arrays.toString(array));
} public static void sort(int[] array) {
int maxStep = calculationStepLength(array.length);
for (int step = maxStep; step > 0; step = (step-1)/3) {
for (int i = step; i < array.length; i++) {
for (int j = i; j > step - 1; j -= step) {
if (array[j-step] > array[j]) {
swapValue(array, j, j - step);
}
}
}
}
} private static int calculationStepLength(int length) {
int res = 1;
while (res < length / 3) {
res = res * 3 + 1;
}
return res;
} private static void swapValue(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
} }

那么,本人来展示下运行结果


快速排序

时间复杂度

O(nlog n)

基本原理

首先选取数组中的第一个数作为基准数

然后将比它大的数放在它的左边比它小的数放在右边

这样一来,这个基准数的位置就找好了

接下来,我们再对左右两个区间的数分别进行如上的操作

重复上面的所有操作,直到每个区间只有一个数为止

动态演示

代码实现

package aboutArraySort;

import java.util.Arrays;

public class QuickSort {

	public static void main(String[] args) {
int[] array = {37, 59, 43, -98, -17, 0};
sort(array);
System.out.println(Arrays.toString(array));
} public static void sort(int[] array) {
qiuckSort(array, 0, array.length-1);
} private static void qiuckSort(int[] array, int start, int end) {
if (start < end) {
int refIndex = getRefIndex(array, start, end);
qiuckSort(array, start, refIndex-1);
qiuckSort(array, refIndex+1, end);
}
} private static int getRefIndex(int[] array, int start, int end) {
int i = start;
int j = end;
int temp = array[start]; while (i < j) {
while (i<j && (array[j]>=temp)) {
j--;
}
if (i < j) {
array[i] = array[j];
i++;
} while (i<j && (array[i]<temp)) {
i++;
}
if (i < j) {
array[j] = array[i];
j--;
}
}
array[i] = temp;
return i;
} }

那么,本人来展示下运行结果


归并排序

时间复杂度

O(nlog n)

基本原理

假设一个数组是由length个有序数组组成的

然后两两排序

之后再将每两个数组元素看作是一个有序序列,再重复上面的步骤

直到将整个数组看作是一个有序序列,那么这个数组就已经排好序了

动态演示

代码实现

package aboutArraySort;

import java.util.Arrays;

public class MergeSort {

	public static void main(String[] args) {
int[] array = {37, 59, 43, -98, -17, 0};
sort(array);
System.out.println(Arrays.toString(array));
} public static void sort(int[] array) {
mergeSort(array, 0, array.length - 1);
} private static void mergeSort(int[] array, int startIndex, int endIndex) {
int centerIndex = (endIndex + startIndex)/2;
if (startIndex < endIndex) {
mergeSort(array, startIndex, centerIndex);
mergeSort(array, centerIndex + 1, endIndex);
merge(array, startIndex ,endIndex);
}
} /* 合并两个子数组 */
private static void merge(int[] array, int startIndex, int endIndex) {
int centerIndex = (endIndex + startIndex)/2;
int i = startIndex;
int j = centerIndex + 1;
int[] res = new int[endIndex - startIndex + 1];
int index = 0; //向临时数组中存储元素
while ((i <= centerIndex) && (j <= endIndex)) {
if (array[i] <= array[j]) {
res[index++] = array[i++];
} else {
res[index++] = array[j++];
}
}
//处理剩余元素
while (i <= centerIndex) {
res[index++] = array[i++];
}
while (j <= endIndex) {
res[index++] = array[j++];
}
//将临时数组中的值转交给原数组
for (int k = 0; k < res.length; k++) {
array[k + startIndex] = res[k];
}
} }

那么,本人来展示下运行结果


基数排序

时间复杂度

O(d(r+n))

(d——长度

r —— 关键字基数

n ——关键字个数)

基本原理

首先来建立编号为0~9的10个数组

然后将原数组中的每个元素通过个位的数值来存放在10个新数组对应的一个当中

然后再按照0~9的顺序将所有存入的数取出

再来按照原数组中的每个值的十位的值,来存放在10个新数组对应的一个当中

重复上面的操作,直到最高位也被这样比较了

等最后一次取出时,这个数组就排好序了

(由于我们设置的数组只能用于识别每一位的值,而不能识别正负,

所以,基数排序只能用于排列正数

动态演示

代码实现

package aboutArraySort;

import java.util.Arrays;

public class RadixSort {

	public static void main(String[] args) {
int[] array = {37, 59, 43, 0};
sort(array);
System.out.println(Arrays.toString(array));
} public static void sort(int[] array) {
int[][] tempArray = new int[10][array.length];
int[] capacity = new int[10];
int max = getMax(array);
int maxLen = String.valueOf(max).length(); for (int i = 0, n = 1; i < maxLen; i++, n *= 10) {
for (int j = 0; j < array.length; j++) {
//取每轮相应的位的值
int remainder = array[j]/n%10;
tempArray[remainder][capacity[remainder]++] = array[j];
}
//取出临时数组中的元素
int index = 0;
for (int k = 0; k < capacity.length; k++) {
if (capacity[k] != 0) {
for (int x = 0; x < capacity[k]; x++) {
array[index++] = tempArray[k][x];
}
//清空临时数组中的记录,以便我们之后再次使用这个数组
capacity[k] = 0;
}
}
} } private static int getMax(int[] array) {
int res = array[0]; if (array.length < 2) {
return res;
}
for (int i = 1; i < array.length; i++) {
if (array[i] > res) {
res = array[i];
}
}
return res;
} }

那么,本人来展示下运行结果


堆排序

时间复杂度

O(nlog n)

基本原理

首先将待排序列构造成一个大根堆,所以,此时的根节点就是整个数组的最大值

然后将根所存储的数值末尾元素进行交换,这样一来,末尾元素就是本数组的最大值

之后将除末尾元素外的剩余元素再次转换为大根堆反复进行上述的操作

剩余最后一个元素时,这个数组排序完成

动态演示

代码实现

package aboutArraySort;

import java.util.Arrays;

public class HeapSort {

	public static void main(String[] args) {
int[] array = {37, 59, 43, -98, -17, 0};
sort(array);
System.out.println(Arrays.toString(array));
} public static void sort(int[] array) {
for (int i = (array.length-1)/2; i >= 0; i--) {
toBigRootHeap(array, array.length, i);
}
for (int i = array.length-1; i > 0; i--) {
//进行调换
swapValue(array, i, 0);
//再将剩余元素调换成大顶堆
toBigRootHeap(array, i, 0);
}
} private static void toBigRootHeap(int[] array, int size, int index) {
//获取左右孩子的下标
int leftChildIndex = index * 2 + 1;
int rightChildIndex = index * 2 + 2;
//获得此根与左右孩子中的最大值的下标
int maxIndex = index;
if ((leftChildIndex < size) && (array[leftChildIndex] > array[maxIndex])) {
maxIndex = leftChildIndex;
}
if ((rightChildIndex < size) && (array[rightChildIndex] > array[maxIndex])) {
maxIndex = rightChildIndex;
}
//交换这三个数值的位置,将此节点转换为“大根”
if (maxIndex != index) {
swapValue(array, index, maxIndex);
//排序底下的节点,防止调换完导致底下的节点无法形成大根堆
toBigRootHeap(array, size, maxIndex);
} } private static void swapValue(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
} }

那么,本人来展示下运行结果


Java数组 —— 八大排序的更多相关文章

  1. 万字长文带你掌握Java数组与排序,代码实现原理都帮你搞明白!

    查找元素索引位置 基本查找 根据数组元素找出该元素第一次在数组中出现的索引 public class TestArray1 { public static void main(String[] arg ...

  2. Java数组的排序算法

    在Java中,实现数组的排序算法有很多,如冒泡排序法.选择排序法.直接插入法和快速排序法等.下面介绍几种排序算法的具体 实现. 本文引用文献:Java必须知道的300个问题. 1.冒泡排序法 1.1 ...

  3. java数组随机排序实现代码

    例一 代码如下 复制代码 import java.lang.Math;import java.util.Scanner;class AarrayReverse{ public static void ...

  4. JAVA:数组,排序,查找<4>

    一.数组 1.一维数组 (1).数组的定义 数据类型 数组名[]=new 数据类型[大小] public class Demo1 { public static void main(String[] ...

  5. java 的八大排序

    import java.util.Arrays;import java.util.*; public class Sort { /** * 插入排序 */ public static void ins ...

  6. java实现八大排序算法

    Arrays.sort() 采用了2种排序算法 -- 基本类型数据使用快速排序法,对象数组使用归并排序. java的Collections.sort算法调用的是归并排序,它是稳定排序 方法一:直接插入 ...

  7. java的八大排序

    public class Sort2 { public static void main(String[] args) { Sort2 sort = new Sort2(); System.out.p ...

  8. java之八大排序

    的关系:  1.直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排 好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数 也是排好顺序的.如此反 ...

  9. java常用八大排序法

    最近查资料发现java排序挺有意思的,其中包含常见八种具有代表性的排序法:笔者觉得排序的功能重要,但更重要的是排序的思想:所以简单叙述一下常见排序方法名称,并用代码举例. A.插入排序(直接插入排序. ...

随机推荐

  1. MySQL5.6 选项和变量整理

    MySQL5.6 选项和变量整理  --allow-suspicious-udfs 这个选项控制是否用户定义函数只有一个xxx符号用于主函数加载.默认,该选项是关闭并且只具有至少一个辅助符号的UDFs ...

  2. 使用Python创建自己的Instagram滤镜

    不知道你有没有使用过Instagram滤镜,它们非常方便,只需单击几个按钮,就可以变换我要发布的照片​​. 你是否想过自己可以创建一个?答案是可以的! 在本文中,我将向你展示如何使用代码和示例图像来创 ...

  3. 热点 | 近期Github热点项目库总结

    整理 | Walker 介绍:你有没有想过你会成为一个艺术家,但无奈你不知道如何画画?得益于计算机视觉技术,你可以在ML社区轻松实现这个梦想.更棒的是,Github上ML社区的代码都是开源的! 这就是 ...

  4. Qt 事件使用示例 (一)

    Qt 事件使用示例,以一个常见的使用来说明:QLabel 当鼠标滑过时改变颜色. 事先说明要想实现这一功能有很多种方法,如Qss实现,本文使用Qt事件的方式来实现. 第一步,我们得实现一个从QLabe ...

  5. java 初学者 第一阶段作业编程总结及心得体会

    0.前言 第一阶段java作业分为3次. 第一次作业是简单得一些语法和一些简单得逻辑思维,主要内容有求三角形是什么三角形的,还有就是求坐标点所在范围的,也涉及到了数字和字母的转换,总之相相当于是给ja ...

  6. Python python对象 range

    """ range(stop) -> range object range(start, stop[, step]) -> range object Retu ...

  7. Vertica的这些事(三)——Vertica中实现Oracle中的ws_concat功能

    vertica中没有类似Oracle中的ws_concat函数功能,需要开发UDF,自己对C++不熟悉,所有只有想其他方法解决了. 上代码: SELECT node_state, MAX(DECODE ...

  8. Light of future-冲刺Day 7

    目录 1.SCRUM部分: 每个成员进度 SCRUM 会议的照片 签入记录 代码运行截图 用户浏览界面 订单详情界面 管理员浏览界面 新增后台界面 2.PM 报告: 时间表 燃尽图 任务总量变化曲线 ...

  9. js之:漂浮线

    (function initJParticle( $ ){ "use strict"; var createParticlesSandbox, Utils; Utils = {}; ...

  10. jmeter发送Query String Parameters格式参数报错

    当发起一次GET请求时,参数会以url string的形式进行传递.即?后的字符串则为其请求参数,并以&作为分隔符 当参数为json格式时,这时需要勾选编码,否则会报错