冒泡排序 O(n2)

两个数比较大小,较大的数下沉,较小的数冒起来。

public static void bubbleSort(int[] a) {
//临时变量
int temp;
//i是循环次数,也是冒泡的结果位置下标,5个数组循环5次
for (int i = 0; i < a.length; i++) {
//从最后向前面两两对比,j是比较中下标大的值
for (int j = a.length - 1; j > i; j--) {
//让小的数字排在前面
if (a[j] < a[j - 1]) {
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
}

选择排序 O(n2)

在长度为N的无序数组中,第一次遍历n-1个数,找到最小的数值与第一个元素交换;

第二次遍历n-2个数,找到最小的数值与第二个元素交换;

。。。

第n-1次遍历,找到最小的数值与第n-1个元素交换,排序完成。

public static void selectSort(int[] a) {
//临时变量
int temp;
//i是循环次数,也是选择交换的结果的位置下标,5个数组循环5次
for (int i = 0; i < a.length; i++) {
//最小值下标
int min = i;
for (int j = i + 1; j < a.length; j++) {
if (a[min] > a[j]) {
min = j;
}
}
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}

插入排序 O(n2)

在要排序的一组数中,假定前n-1个数已经排好序,现在将第n个数插到前面的有序数列中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

public static void insertSort(int[] a) {
int temp;
//i是循环次数,也是插入的队列的长度,最后一位是a[i]
//所以一开始a[0]是排好的一个队列,比较a.length-1次,最后一次循环是a[a.length-1]插入a[0]~a[a.length-2]
for (int i = 0; i < a.length - 1; i++) {
//a[j]是要插入的数字,从a[j]往a[0]比较
for (int j = i + 1; j > 0; j--) {
//如果插入的数小,交换位置
if (a[j] < a[j - 1]) {
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
} else {
//因为默认a[0]~a[i]是排好的,a[i+1]比a[i]大的话,就不用比较后面了
break;
}
}
}
}

希尔排序 O(n1.5)

在要排序的一组数中,根据某一增量分为若干子序列,并对子序列分别进行插入排序。

然后逐渐将增量减小,并重复上述过程。直至增量为1,此时数据序列基本有序,最后进行插入排序。

public static void shellSort(int[] a) {
int temp;
int d = a.length;
for (; ; ) {
d = d / 2;
//根据差值分组为子序列
for (int k = 0; k < d; k++) {
//此时对每组数列进行插入排序,数组为a[k+d],a[k+2d]...a[k+n*d]
for (int i = k + d; i < a.length; i += d) {
// a[j]是要插入的数字,从a[j]往a[0]比较,跨度为d
for (int j = i; j > k; j -= d) {
//如果插入的数小,交换位置
if (a[j] < a[j - d]) {
temp = a[j];
a[j] = a[j - d];
a[j - d] = temp;
} else {
//因为默认a[0]~a[i]是排好的,a[i+1]比a[i]大的话,就不用比较后面了
break;
}
}
}
}
if (d == 1) {
break;
}
}
}

快速排序 O(N*logN)

先从数列中取出一个数作为base值;

将比这个数小的数全部放在它的左边,大于或等于它的数全部放在它的右边;

对左右两个小数列重复第二步,直至各区间只有1个数。

public void quickSort(int a[], int l, int r) {
//左边必须大于右边
if (l >= r) {
return;
}
int i = l;
int j = r;
//选择第一个数为基准
int base = a[l];
while (i < j) {
//从右向左找第一个小于base的值,如果大于左移一位,直到找到小值或者i/j重合
while (i < j && a[j] > base) {
j--;
}
//从左向右找第一个大于base的值,如果小于右移一位,直到找到大值或者i/j重合
while (i < j && a[i] < base) {
i++;
}
//交换
if (i < j) {
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
//将基准值放到i右移到的位置
a[i] = base;
//将i左边和i右边分别排序
quickSort(a, l, i - 1);//递归调用
quickSort(a, i + 1, r);//递归调用
}

归并排序 O(N*logN)

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。

首先考虑下如何将2个有序数列合并。

这个非常简单,只要从比较2个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。

然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。

private static void mergeSort(int[] a, int first, int last, int temp[]) {
if (first < last) {
//中间值
int middle = (first + last) / 2;
//左半部分排序
mergeSort(a, first, middle, temp);
//右半部分排序
mergeSort(a, middle + 1, last, temp);
//合并左右部分
mergeArray(a, first, middle, last, temp);
}
} private static void mergeArray(int a[], int first, int middle, int end, int temp[]) {
int i = first;
int m = middle;
int j = middle + 1;
int n = end;
int k = 0;
while (i <= m && j <= n) {
if (a[i] <= a[j]) {
temp[k] = a[i];
k++;
i++;
} else {
temp[k] = a[j];
k++;
j++;
}
}
while (i <= m) {
temp[k] = a[i];
k++;
i++;
}
while (j <= n) {
temp[k] = a[j];
k++;
j++;
}
for (int r = 0; r < k; r++) {
a[first + r] = temp[r];
}
}

堆排序 O(N*logN)

利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

public static void heapSort(int a[]) {
//堆顶最大值和数组最后(叶节点)交换 长度-1 次
for (int i = a.length - 1; i > 0; i--) {
//构建大顶堆(最大堆)
buildHeap(a, i);
//堆顶最大值和数组最后(叶节点)交换
swap(a, 0, i);
}
} //构建大顶堆(最大堆)
public static void buildHeap(int a[], int lastIndex) {
//排最后的非叶节点为 长度/2-1,从第i检查到堆顶第0项,上浮大值
for (int i = (lastIndex + 1) / 2 - 1; i >= 0; i--) {
//必定存在的左叶节点,不一定存在的右叶节点
int left = i * 2 + 1;
int right = i * 2 + 2;
//max为左右叶节点中的最大值
int max = left;
if (right <= lastIndex) {
if (a[left] < a[right]) {
max = right;
}
}
//上浮大值
if (a[i] < a[max]) {
swap(a, i, max);
}
}
} //交换值
public static void swap(int a[], int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}

基数排序 O(d(n+r))

【d代表关键字有d位,n代表n个记录,r代表r个空队列】

基数排序(radix sort),相对于常见的比较排序,基数排序是一种分配式排序,即通过将所有数字分配到应在的位置最后再覆盖到原数组完成排序的过程。

public static void radixSort(int[] a) {
//位数
int digit = 1;
//作为排序后数组的新下标
int newIndex = 0;
//供基数排序使用的二维数组,第一维度固定10位0~9,第二维度根据下标依次存放每次基数排序的结果
int[][] container = new int[10][a.length];
//第一维度每个数组的内容计数,最少为10,防止数组全是个位数时越界,例如五位数组最大值为8,counter.length=5 ,counter[8]就越界
int counterLength = 10;
if (a.length > 10) {
counterLength = a.length;
}
int[] counter = new int[counterLength];
//算出数组中最大的值,用来确定最大位
int max = a[0];
int maxDigit = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] > max) {
max = a[i];
}
}
while (max > 0) {
max /= 10;
maxDigit++;
}
//对每位进行排序
while (digit <= maxDigit) {
//对每个数值该位取余,container[remainder],并计数该位置上数值的下标counter[remainder]
for (int num : a) {
int remainder = (num / digit) % 10;
container[remainder][counter[remainder]] = num;
counter[remainder]++;
}
//将上一步放入容器的数值依次覆盖到远数组中
for (int i = 0; i < 10; i++) {
for (int j = 0; j < counter[i]; j++) {
a[newIndex] = container[i][j];
newIndex++;
}
counter[i] = 0;
}
digit *= 10;
newIndex = 0;
}
}

8种排序算法 Java实现的更多相关文章

  1. 八种排序算法--java实现(转)

    (转:http://blog.csdn.net/without0815/article/details/7697916) 8种排序之间的关系: 1, 直接插入排序 (1)基本思想:在要排序的一组数中, ...

  2. 学习Java绝对要懂的,Java编程中最常用的几种排序算法!

    今天给大家分享一下Java中几种常见的排序算法的Java代码 推荐一下我的Java学习羊君前616,中959,最后444.把数字串联起来!     ,群里有免费的学习视频和项目给大家练手.大神有空时也 ...

  3. java算法03 - 常用的8种排序算法

    Java常用的八种排序算法: 插入排序 - 直接插入排序 每次将待排序的记录按照关键字的大小,插入到前面已经排好序的记录的适当位置.直到全部记录插入完成. 代码实现 /** * 直接插入排序 O(n^ ...

  4. 几种排序算法及Java实现排序的几种方式

    几种排序算法 下面的例子介绍了4种排序方法: 冒泡排序, 选择排序, 插入排序, 快速排序 package date201709.date20170915; public class SortUtil ...

  5. Java 的八种排序算法

    Java 的八种排序算法 这个世界,需要遗忘的太多. 背景:工作三年,算法一问三不知. 一.八种排序算法 直接插入排序.希尔排序.简单选择排序.堆排序.冒泡排序.快速排序.归并排序和基数排序. 二.算 ...

  6. 八大排序算法Java

    目录(?)[-] 概述 插入排序直接插入排序Straight Insertion Sort 插入排序希尔排序Shells Sort 选择排序简单选择排序Simple Selection Sort 选择 ...

  7. 八大排序算法Java实现

    本文对常见的排序算法进行了总结. 常见排序算法如下: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 它们都属于内部排序,也就是只考虑数据量较小仅需要使用内存的排 ...

  8. 几种排序算法的学习,利用Python和C实现

    之前学过的都忘了,也没好好做过总结,现在总结一下. 时间复杂度和空间复杂度的概念: 1.空间复杂度:是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了,简单说就是递归集算 ...

  9. 秒杀9种排序算法(JavaScript版)

    一:你必须知道的 1> JS原型 2> 排序中的有序区和无序区 3> 二叉树的基本知识 如果你不知道上面三个东西,还是去复习一下吧,否则,看下面的东西有点吃力. 二:封装丑陋的原型方 ...

随机推荐

  1. Freemarker + iTextRender 实现根据模板网页生成PDF

    #0 背景 工作需要实现导出PDF的功能,在进行简单调研后,我决定采用Freemarker + iTextRender进行实现. 基本思路如下: Freemarker实现根据动态数据渲染出需要导出的H ...

  2. Java方法的定义以及调用、方法重载、可变参数以及递归

    目录 何谓方法 方法的定义及调用 方法的定义 方法调用 方法重载 命令行传参 可变参数 递归 何谓方法 Java方法是语句的集合,它们在一起执行一个功能 方法是解决一类问题的步骤的有序组合 方法包含于 ...

  3. 手机端页面访问PC页面自动跳手机端代码

    <script> var mobileAgent = new Array("iphone", "ipod", "ipad", & ...

  4. JS中Class的两种写法

    写法一:使用函数: var ClassName = function() { this.message = 'dat.gui'; this.speed = 0.8; this.displayOutli ...

  5. uniapp轻轻松松开发各种类型的小程序

    1.前言 现在移动端用户使用量占据了市场大部分的比例,今天 给大家说说怎么去开发一个小程序,今天使用的是uniapp 2.什么是uniapp uni-app 是一个使用 Vue.js 开发所有前端应用 ...

  6. Java——参数传递

    写这篇文章时,其实还是不理解Java中的参数传递只有传值没有传址(传引用).这里引用知乎上大神的讲解来记录一下. 一.基本类型和引用类型 int num = 10; String str = &quo ...

  7. MySQL死锁系列-常见加锁场景分析

    在上一篇文章<锁的类型以及加锁原理>主要总结了 MySQL 锁的类型和模式以及基本的加锁原理,今天我们就从原理走向实战,分析常见 SQL 语句的加锁场景.了解了这几种场景,相信小伙伴们也能 ...

  8. Cypress系列(4)- 解析 Cypress 的默认文件结构

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 默认文件结构 在使用 cypress o ...

  9. jQuery-ajax请求使用

    1.jQuery中的ajax $.ajax({ url:'地址', type:'get/post', data:{}, dataType:'json/jsonp', success:function( ...

  10. for循环的嵌套 函数方法

    1.双层for循环:外层循环控制行,内行循环控制列 for循环嵌套例子 用五角星组成一个矩形 // 99乘法表 // for(var i = 1 ;i <= 9 ; i++){ //     f ...