八大排序算法的java实现
有时间再贴算法分析图
JDK7的Collections.sort()的算法是TimSort, 适应性的归并排序, 比较晦涩难懂, 这里没有实现
public class mySort { // 冒泡排序
public static void myBubbleSort(int[] array) {
int lastExchange = array.length - 1; //记录最后交换位置, 避免重复比较
for (int i = lastExchange - 1; i >= 0; --i) {
for (int j = 0; j <= i; ++j) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
lastExchange = j; //特性:最后交互位置后的元素已经有序
}
}
}
} // 插入排序
public static void myInsertSort(int[] array) {
for (int i = 1; i <= array.length - 1; ++i) {
int temp = array[i];
int j = 0; // 给值移位并寻找插入点
for (j = i - 1; j >= 0 && array[j] > temp; --j) {
array[j + 1] = array[j];
}
array[j + 1] = temp;
}
} // 选择排序
public static void mySelectSort(int[] array) {
for (int i = 0; i < array.length - 1; ++i) {
int minIndex = i;
// 每次选出一极值
for (int j = i + 1; j <= array.length - 1; ++j) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
// 极值归位
if (minIndex != i) {
int temp = array[minIndex];
array[minIndex] = array[i];
array[i] = temp;
}
}
} // 希尔排序
public static void myShellSort(int[] array) {
int gap = 5;
while (gap != 0) {
//不必刻意分组, 组1->组2->组1->组2...轮流处理
for (int j = gap; j <= array.length - 1; ++j) {
int temp = array[j];
int k = 0;
for (k = j - gap; k >= 0 && array[k] > temp; k -= gap) {
array[k + gap] = array[k];
}
array[k + gap] = temp;
}
gap /= 2; //重新分组
}
} // 快速排序
public static void myQuickSort(int[] array) {
myQuickSortCore(array, 0, array.length - 1);
}
private static void myQuickSortCore(int[] array, int left, int right) {
if (left >= right) { //递归出口
return;
}
int mLeft = left;
int mRight = right; int base = array[mLeft]; //第一个元素作为基准, left空位可占
while(mLeft != mRight) {
while (mRight > mLeft && array[mRight] >= base) {
--mRight;
}
array[mLeft] = array[mRight]; //right可覆盖
while (mRight > mLeft && array[mLeft] <= base) {
++mLeft;
}
array[mRight] = array[mLeft];
}
array[mRight] = base; //基准元素归位, l=r myQuickSortCore(array, left, mLeft - 1); //递归基准以左
myQuickSortCore(array, mRight + 1 , right); //递归基准以右
} // 归并排序
public static void myMergeSort(int[] array) {
// 每个分组中有两个来自上层迭代的有序组, gap为有序组长度, 2 * gap为分组长度
for (int gap = 1; gap < array.length; gap *= 2) {
int i = 0; // array下标
// 分组并内部排序
while (i + 2 * gap - 1 < array.length) {
mergePiece(array, i, i + gap - 1, i + 2 * gap - 1);
i += 2 * gap;
}
// 分组剩余部分排序, 只有超过一个gap才有内部排序的意义
if (i + gap - 1 < array.length) {
mergePiece(array, i, i + gap - 1, array.length - 1);
}
}
}
// 将array中有序的两段piecewise1 和 piecewise2 合并成整体有序
public static void mergePiece(int[] array, int head, int mid, int tail) {
int i = head; // piecewise1下标 [head, mid]
int j = mid + 1; // piecewise2下标 [mid + 1, tail]
// 临时数组, 保存结果
int[] arrayTemp = new int[tail - head + 1]; // combine
int k = 0; // combine下标
while (i <= mid && j <= tail) {
if (array[i] <= array[j]) {
arrayTemp[k] = array[i];
++i;
++k;
} else {
arrayTemp[k] = array[j];
++j;
++k;
}
}
// 复制多余部分 piecewise1
while (i <= mid) {
arrayTemp[k] = array[i];
++i;
++k;
}
// 复制多余部分 piecewise2
while (j <= tail) {
arrayTemp[k] = array[j];
++j;
++k;
}
// 结果复制到原始数组
k = 0;
i = head; // 重置下标, i piecewise1 + piecewise2
while (i <= tail) {
array[i] = arrayTemp[k];
++i;
++k;
}
} // 堆排序
public static void myHeapSort(int[] array) {
// 调整堆->大顶堆
for (int i = array.length / 2 - 1; i >= 0; --i) { // 从最后非叶子节点开始
adjustHeap(array, i, array.length);
}
// 调整堆->交换堆顶/末位元素
for (int j = array.length - 1; j > 0; --j) {
int temp = array[0];
array[0] = array[j];
array[j] = temp;
adjustHeap(array, 0, j); // 只需调整堆顶父节点
}
}
// 调整为大顶堆分布, node为父节点下标, adjustLen为涉及调整的长度(为排序使用)
private static void adjustHeap(int[] array, int node, int adjustLen) {
int temp = array[node]; // 拿出node形成可占空位
for (int i = node * 2 + 1; i < adjustLen; i = node * 2 + 1) {
if (i + 1 < adjustLen && array[i] < array[i + 1]) {
++i; // 得到最大子节点
}
if (array[i] > temp) {
array[node] = array[i];
node = i; // 为下一层迭代更新父节点node, 最后为叶子
} else {
break;
}
}
array[node] = temp;
} // 基数排序
public static void myRadixSort(int[] array) {
int d = maxBit(array);
int dec = 1; //进制迭代
final int R = 10; //桶个数
int[] tempArray = new int[array.length]; //临时数组, 代替桶存储数组, 代价是需记录下标/数量来分割桶
int[] bucketCapacity = new int[R]; //桶计数
for (int i = 1; i <= d; ++i) {
for (int j = 0; j < R; ++j) {
bucketCapacity[j] = 0; //清空桶容量
}
//计数1
for (int j = 0; j < array.length; ++j) {
int k = array[j] / dec % R;
++bucketCapacity[k];
}
//计数2 变累计, 为分割
for (int j = 1; j < R; ++j) {
bucketCapacity[j] = bucketCapacity[j - 1] + bucketCapacity[j];
}
// 存储进桶
for (int j = array.length - 1; j >= 0; --j) {
int k = array[j] / dec % R;
tempArray[bucketCapacity[k] - 1] = array[j];
--bucketCapacity[k];
}
// 写出
for(int j = 0; j < array.length; ++j) {
array[j] = tempArray[j];
}
// 下一位
dec *= 10;
} }
//求数组元素的最大位数
private static int maxBit(int[] array) {
int bit = 1;
int dec = 10;
for (int i = 0; i < array.length; ++i) {
while (array[i] >= dec) {
++bit;
dec *= 10;
}
}
return bit;
}
}
八大排序算法的java实现的更多相关文章
- 八大排序算法的Java代码实现
简单插入排序 public class QuickSort { private static void quickSort(int [] a, int low, int high){ if (low ...
- 八大排序算法Java实现
本文对常见的排序算法进行了总结. 常见排序算法如下: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 它们都属于内部排序,也就是只考虑数据量较小仅需要使用内存的排 ...
- 八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)
一.分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程. 外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排序过程中需 ...
- Java八大排序算法
Java八大排序算法: package sort; import java.util.ArrayList; import java.util.Arrays; import java.util.List ...
- 八大排序算法总结与java实现(转)
八大排序算法总结与Java实现 原文链接: 八大排序算法总结与java实现 - iTimeTraveler 概述 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 ...
- 八大排序算法 JAVA实现 亲自测试 可用!
今天很高兴 终于系统的实现了八大排序算法!不说了 直接上代码 !代码都是自己敲的, 亲测可用没有问题! 另:说一下什么是八大排序算法: 插入排序 希尔排序 选择排序 堆排序 冒泡排序 快速排序 归并排 ...
- 常见排序算法(附java代码)
常见排序算法与java实现 一.选择排序(SelectSort) 基本原理:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换:接着对不包括第一个记录以外的其他 ...
- 几大排序算法的Java实现
很多的面试题都问到了排序算法,中间的算法和思想比较重要,这边我选择了5种常用排序算法并用Java进行了实现.自己写一个模板已防以后面试用到.大家可以看过算法之后,自己去实现一下. 1.冒泡排序:大数向 ...
- [Data Structure & Algorithm] 八大排序算法
排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.我们这里说的八大排序算法均为内部排序. 下图为排序 ...
随机推荐
- hibernate自动建表之engine设置
1.MYSQL的数据库引擎中,只有InnoDB和BDB(Berkley DB )包括了对事务处理和外键的支持.如果数据引擎建为MyISAM则rollback无效. 2.而hibernate自动建表的时 ...
- SAP 后台job
SAP 如何定义后台job 有两种方 1是se38执行可执行程序后,菜单栏‘程序’--->'后台执行',输入输出设备,ENTER两次后,选择开始时间(立刻执行,或定义日期时间,也可周期执行..) ...
- java线程小结1
1.创建线程的两种方法 新线程的创建和启动都是通过java代码触发的.除了第一个线程(也就是启动程序的.运行main()方法的线程)是由java平台直接创建的之外,其余的线程都是在java代码中通过“ ...
- SharePoint 2010 以Jquery Ajax方式更新SharePoint列表数据!
之前本人的博客介绍了<sharepoint 2010自定义访问日志列表设置移动终端否和客户端访问系统等计算列的公式>,那如何通过Jquery提交访问日志到自定义的SharePoint的访问 ...
- LeetCode:课程表【207】
LeetCode:课程表[207] 题目描述 现在你总共有 n 门课需要选,记为 0 到 n-1. 在选修某些课程之前需要一些先修课程. 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹 ...
- NIO服务端和客户端通信demo
代码转自 https://www.jianshu.com/p/a9d030fec081 服务端: package nio; import java.io.IOException; import jav ...
- solr 利用cul或solr界面单值更新
本文主要是指利用solr界面或cul的更新solr的值.如果需要代码中单值更新请参考黎明露珠的博客链接:http://www.cnblogs.com/limingluzhu/p/5535314.htm ...
- 搭建Mac OS X下cocos2d-x的Android开发环境
版本 Cocos2d-x: cocos2d-2.1beta3-x-2.1.1 OS X: 10.8 Android ADT Bundle: v21.1.0 Android NDK: android-n ...
- NGUI 3.50 UIButton使用
在NGUI,3.X的版本中,取消了创建UIbutton这个选项,所以我们可以创建uisprite.uilabel等,然后在上面附加uibutton脚本,达到目的,具体步骤 1:在界面上键好2D或3D ...
- adas--智能驾驶辅助系统
先进驾驶辅助系统(Advanced Driver AssistantSystem),简称ADAS,是利用安装于车上的各式各样的传感器(可侦测光.热.压力等变数), 在第一时间收集车内外的环境数据, 进 ...