虽然排序算法烂大街了,但是哥依然用java实现了一遍,只为自己练练手,后面可以时不时的回头看看。。。仅此而已,各位可以提意见,莫喷!!

一、冒泡排序

  基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换

 /**
* 冒泡排序
* @param data 要排序的数组
* @param reverse 从大到小(false)还是从小到大(ture)
*/
public static void sort(int[] data, boolean reverse) {
if (data.length == 1) {
return;
}
for (int i = 0; i < data.length - 1; i++) {
int tmp = 0;
for (int j = 0; j < data.length - i - 1; j++) {
if (reverse) { //从小到大(ture)
if (data[j] >= data[j+1]) {
tmp = data[j];
data[j] = data[j +1 ];
data[j+1] = tmp;
}
} else { //从大到小(false)
if (data[j] <= data[j+1]) {
tmp = data[j+1];
data[j+1] = data[j];
data[j] = tmp;
}
}
}
}
}

二、堆排序

  基本思想:堆排序是一种树形选择排序,是对直接选择排序的有效改进。

  堆的定义如下:具有n个元素的序列(h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆。在这里只讨论满足前者条件的堆。由堆的定义可以看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。完全二叉树可以很直观地表示堆的结构。堆顶为根,其它为左子树、右子树。初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数  

 /**
* 堆排序
* @param data 要排序的数组
* @param reverse 从大到小(false)还是从小到大(ture)
*/
public static void sort(int[] data, boolean reverse) {
if (data.length == 1) {
return;
}
for (int i = 0; i < data.length; i++) {
//建堆
buildHeap(data, 0, data.length -1 - i, reverse);
int tmp = data[0];
data[0] = data[data.length - 1 - i];
data[data.length - 1 - i] = tmp;
}
} /**
* 将指定开始和结束段的数据建堆
* @param data
* @param beginIndex
* @param endIndex
* @param reverse
*/
public static void buildHeap(int[] data, int beginIndex, int endIndex, boolean reverse) {
if (beginIndex >= endIndex) {
return;
}
for (int i = (endIndex + beginIndex - 1) / 2; i >= beginIndex; i--) {
int cur = i;
if (reverse) { //大顶堆,用来从小到大排序
//发生交换之后需要检查孙子节点,重孙子节点...
while (2 * cur + 1 <= endIndex) {
int biggerChildIndex = 2 * cur + 1;
if (biggerChildIndex + 1 <= endIndex) {
if (data[biggerChildIndex] < data[biggerChildIndex + 1]) {
biggerChildIndex = biggerChildIndex + 1;
}
}
//找到最大子节点,如果比当前节点大,就交换
if (data[i] < data[biggerChildIndex]) {
int tmp = data[i];
data[i] = data[biggerChildIndex];
data[biggerChildIndex] = tmp;
//准备检查孙子节点
cur = biggerChildIndex;
} else {
break;
}
}
} else { //小顶堆,用来从大到小排序
//发生交换之后需要检查孙子节点,重孙子节点...
while (2 * cur + 1 <= endIndex) {
int samllerChildIndex = 2 * i + 1;
if (samllerChildIndex + 1 <= endIndex) {
if (data[samllerChildIndex] > data[samllerChildIndex + 1]) {
samllerChildIndex = samllerChildIndex + 1;
}
}
//找到最小子节点,如果比当前节点小,就交换
if (data[i] > data[samllerChildIndex]) {
int tmp = data[i];
data[i] = data[samllerChildIndex];
data[samllerChildIndex] = tmp;
cur = samllerChildIndex;
} else {
break;
}
}
}
}
}

三、直接插入排序

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

 /**
* 插入排序
* @param data 要排序的数组
* @param reverse 从大到小(false)还是从小到大(ture)
*/
public static void sort(int[] data, boolean reverse) {
if (data.length == 1) {
return;
}
int tmp = 0;
for (int i = 1; i < data.length; i++) {
tmp = data[i];
int n = i - 1;
for (; n >= 0; n--) {
if (reverse) { //从小到大排序
if (data[n] >= tmp) {
data[n + 1] = data[n]; //将大于当前值的数后移一个位置
} else {
break;
}
} else { //从大到小排序
if (data[n] <= tmp) {
data[n + 1] = data[n]; //将小于当前值的数后移一个位置
} else {
break;
}
}
}
data[n+1] = tmp;
}
}

四、归并排序

  基本思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

  /**
* 归并排序
* @param data 要排序的数组
* @param reverse 从大到小(false)还是从小到大(ture)
*/
public static void sort(int[] data, int left, int right, boolean reverse) {
if (left >= right) {
return;
}
int mid = (left + right) / 2;
sort(data, left, mid, reverse);
sort(data, mid + 1, right, reverse);
merge(data, left, mid, right, reverse);
} /**
* 合并已排序好的两段
* @param data
* @param left
* @param mid
* @param right
* @param reverse
*/
public static void merge(int[] data, int left, int mid, int right, boolean reverse) {
int[] tmp = new int[right - left + 1];
int i = left;
int j = mid + 1;
int n = 0;
while (i <= mid && j <= right) {
if (reverse) { //从小到大
if (data[i] <= data[j]) {
tmp[n++] = data[i++];
} else {
tmp[n++] = data[j++];
}
} else { //从大到小
if (data[i] <= data[j]) {
tmp[n++] = data[j++];
} else {
tmp[n++] = data[i++];
}
}
}
while (i <= mid) {
tmp[n++] = data[i++];
}
while (j <= right) {
tmp[n++] = data[j++];
}
for (int k = 0; k < tmp.length; k++) {
data[left + k] = tmp[k];
}
}

五、快递排序

  基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分

    /**
* 快速排序
* @param data
* @param left
* @param right
* @param reverse 从大到小(false)还是从小到大(ture)
*/
public static void sort(int[] data, int left, int right, boolean reverse) {
if (left >= right) {
return;
}
int index = getIndex(data, left, right, reverse);
sort(data, left, index - 1, reverse);
sort(data, index + 1, right, reverse);
} /**
* 将待排序片段调整顺序,获得"中间数据"的正确索引
* @param data
* @param left
* @param right
* @param reverse 从大到小(false)还是从小到大(ture)
* @return
*/
public static int getIndex(int[] data, int left, int right, boolean reverse) {
int cur = data[left];
int i = left;
int j = right;
while (i < j) {
if (reverse) { //从小到大
while (data[j] > cur && i < j) {
--j;
}
data[i] = data[j];
while (data[i] <= cur && i < j) {
++i;
}
data[j]=data[i];
} else { //从大到小
while (data[j] < cur && i < j) {
--j;
}
data[i]=data[j];
while (data[i] >= cur && i < j) {
++i;
}
data[j]=data[i];
}
}
data[i] = cur;
return i;
}

六、基数排序

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

     /**
* 基数排序
* @param data 要排序的数组
* @param reverse 从大到小(false)还是从小到大(ture)
*/
public static void sort(int[] data, boolean reverse) {
if (data.length == 1) {
return;
}
int max = 0;
for (int i = 0; i < data.length; i++) { //找出最大的数据
if (max < data[i]) {
max = data[i];
}
}
System.out.println("the max number is :" + max);
int radix = 1;
ArrayList<ArrayList<Integer>> numbers = new ArrayList<ArrayList<Integer>>(10);
for (int i = 0; i < 10; i++) {
numbers.add(i, new ArrayList<Integer>());
}
while (max > radix) {
for (int i = 0; i < data.length; i++) {
int index = (data[i] / radix) % 10;
ArrayList<Integer> list = numbers.get(index);
list.add(data[i]);
numbers.set(index, list);
}
resetOrder(data, numbers, reverse);
radix = radix * 10;
}
} /**
* 重新调整数组顺序
* @param data
* @param numbers
* @param reverse 从大到小(false)还是从小到大(ture)
*/
public static void resetOrder(int[] data, ArrayList<ArrayList<Integer>> numbers, boolean reverse) {
int n = 0;
if (reverse) {
for (int i = 0; i < numbers.size(); i++) {
ArrayList<Integer> list = numbers.get(i);
while(list.size()>0){
data[n++] = list.get(0);
list.remove(0);
}
}
} else {
for (int i = numbers.size() - 1; i >= 0; i--) {
ArrayList<Integer> list = numbers.get(i);
while(list.size()>0){
data[n++] = list.get(0);
list.remove(0);
}
}
}
}

七、选择排序

  基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

     /**
* 选择排序
* @param data 要排序的数组
* @param reverse 从大到小(false)还是从小到大(ture)
*/
public static void sort(int[] data, boolean reverse) {
if (data.length == 1) {
return;
}
for(int i=0;i<data.length-1;i++){
int tmp=data[i]; //要初始化
int index = i; //要初始化
for(int j=i;j<data.length;j++){
if(reverse) { //从小到大(ture)
if (tmp>=data[j]){
tmp = data[j]; //最小值
index = j;
}
}else {
if (tmp<=data[j]){
tmp = data[j]; //最大值
index = j;
}
}
}
data[index] = data[i];
data[i] = tmp;
}
}

八、希尔排序

  基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成。

     /**
* 希尔排序
* @param data 要排序的数组
* @param reverse 从大到小(false)还是从小到大(ture)
*/
public static void sort(int[] data, boolean reverse) {
if (data.length == 1) {
return;
}
for (int d = data.length / 2; d >= 1; d = d / 2) { //组大小
for (int k = 0; k < d; k++) { //多少组
for (int n = d + k; n < data.length; n = n + d) { //同一组
int cur = n;
while (cur - d >= 0) { //插入排序
int tmp = 0;
if (reverse) { //小到大(ture)
if (data[cur] <= data[cur - d]) {
tmp = data[cur];
data[cur] = data[cur - d];
data[cur - d] = tmp;
}
} else { //从大到小(false)
if (data[cur] >= data[cur - d]) {
tmp = data[cur];
data[cur] = data[cur - d];
data[cur - d] = tmp;
}
}
cur = cur - d;
}
}
}
} }

相关的资料大伙可以自行寻找,本文就不详细介绍了。。。 都烂大街了。。。

以下是一些不错的相关文章

参考:

  1.http://blog.csdn.net/qy1387/article/details/7752973#0-tsina-1-35851-397232819ff9a47a7b7e80a40613cfe1

  2.http://www.cnblogs.com/luxiaoxun/archive/2012/09/01/2666677.html

  3.http://www.cnblogs.com/yefengmeander/archive/2008/12/05/2887903.html

  4.http://blog.jobbole.com/79288/

  5.https://github.com/ztgu/sorting_algorithms_py

就当自己回顾知识了

  

八大常见内排序java实现的更多相关文章

  1. 一些常见的Java面试题 & 面试感悟

    < 前言 > 近期在面试,深感这个行业的浮躁,一些菜不辣基的弱鸡开出的工资待遇要求,超过了我.不知道他们是怎么拿到那么高的工资的,难道是他在公司有亲戚朋友吗?有后台吗?是行业热钱真的过多了 ...

  2. 200个最常见的JAVA面试问题(附答案)

    本文内容: 20个最常见的JAVA面试问题(附答案) 13个单例模式JAVA面试问题(附答案) 说说JVM和垃圾收集是如何工作的(附答案) 说说如何避免JAVA线程死锁(附答案) Java中HashS ...

  3. 最常见的Java面试题及答案汇总(三)

    上一篇:最常见的Java面试题及答案汇总(二) 多线程 35. 并行和并发有什么区别? 并行是指两个或者多个事件在同一时刻发生:而并发是指两个或多个事件在同一时间间隔发生. 并行是在不同实体上的多个事 ...

  4. 最常见的Java面试题及答案汇总(二)

    上一篇:最常见的Java面试题及答案汇总(一) 容器 18. java 容器都有哪些? 常用容器的图录: 19. Collection 和 Collections 有什么区别? java.util.C ...

  5. Java 实现常见内排序

    一.内排序 1.排序基本概念 (1)什么是排序? 排序指将一个数据元素集合或者序列 按照某种规则 重新排列成一个 有序的集合或者序列.分为内排序.外排序.排序算法的好坏直接影响程序的执行速度以及存储空 ...

  6. 八大排序算法Java

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

  7. 八大排序算法Java实现

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

  8. 常见的java 错误--转

    Java常见错误列表: 找不到符号(symbol) 类X是public的,应该被声明在名为X.java的文件中 缺失类.接口或枚举类型 缺失X 缺失标识符 非法的表达式开头 类型不兼容 非法的方法声明 ...

  9. 常见的Java面试题整理

    面试是我们每个人都要经历的事情,大部分人且不止一次,这里给大家总结常见的面试题,让大家在找工作时候能够事半功倍. 1 Switch能否用string做参数? a.在 Java 7 之前, switch ...

随机推荐

  1. 怎样将SQL Azure数据库备份到本地或者Storage

    怎样备份SQL Azure数据库到本地或者云存储Storage,可以使用SQL Database Import Export 的功能. 具体操作如下: 用SSMS链接SQL Azure数据库 注意:服 ...

  2. angular例子笔记

    学习angular的插件写法和制作; <!DOCTYPE html> <html ng-app="APP"> <head> <meta c ...

  3. 【Moqui业务逻辑翻译系列】Story of Online Retail Company 在线零售公司的故事

    h1. Story of Online Retail Company 在线零售公司的故事 Someone decides to sell a product. [Product Marketer Ma ...

  4. HOW TO REMOTELY DEBUG APPLICATION RUNNING ON TOMCAT FROM WITHIN INTELLIJ IDEA

    This post would look into how to tackle and debug issues in scenarios where they only occur in produ ...

  5. 这些天自身努力的体会,关于java方面的

    以前也是接触过java,这学期的软件工程课和周围同学各种比赛取得不错的成绩,确实令人倍感压力.为此这几天使劲脑补了一下java的知识,甚至不惜为此翘课,了解了java中的网络编程,对于sokectse ...

  6. [转]ORACLE 中ROWNUM用法总结!

    原文地址:http://www.itpub.net/thread-824147-1-1.html 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between ...

  7. 【项目开发】LigerUI+MVC的应用

    1.RazorJS 2.@Html.Raw     表示不对输出进行转义

  8. VS中两个常用辅助工具

    一. 首当推荐的是DPack 下载地址:http://www.usysware.com/dpack/ 快捷键:以下都是个人常用的热键.其他还有,我都用得比较少了,3个已经完全够了 Alt+U   查找 ...

  9. emberJS

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  10. Python 之我见

    读音 Python(KK 英语发音:/ˈpaɪθən/) 序言 其实早前就已经接触了python这个功能强大的脚本语言,但是那时只是基于兴趣而学习,目的性并不是很强,所以学习的并不是很深入.最近由于闲 ...