八大常见内排序java实现

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

一、冒泡排序

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

 1 /**
 2      * 冒泡排序
 3      * @param data    要排序的数组
 4      * @param reverse 从大到小(false)还是从小到大(ture)
 5      */
 6     public static void sort(int[] data, boolean reverse) {
 7         if (data.length == 1) {
 8             return;
 9         }
10         for (int i = 0; i < data.length - 1; i++) {
11             int tmp = 0;
12             for (int j = 0; j < data.length - i - 1; j++) {
13                 if (reverse) {  //从小到大(ture)
14                     if (data[j] >= data[j+1]) {
15                         tmp = data[j];
16                         data[j] = data[j +1 ];
17                         data[j+1] = tmp;
18                     }
19                 } else {    //从大到小(false)
20                     if (data[j] <= data[j+1]) {
21                         tmp = data[j+1];
22                         data[j+1] = data[j];
23                         data[j] = tmp;
24                     }
25                 }
26             }
27         }
28     }

二、堆排序

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

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

 1 /**
 2      * 堆排序
 3      * @param data    要排序的数组
 4      * @param reverse 从大到小(false)还是从小到大(ture)
 5      */
 6     public static void sort(int[] data, boolean reverse) {
 7         if (data.length == 1) {
 8             return;
 9         }
10         for (int i = 0; i < data.length; i++) {
11             //建堆
12             buildHeap(data, 0, data.length -1 - i, reverse);
13             int tmp = data[0];
14             data[0] = data[data.length - 1 - i];
15             data[data.length - 1 - i] = tmp;
16         }
17     }
18
19     /**
20      * 将指定开始和结束段的数据建堆
21      * @param data
22      * @param beginIndex
23      * @param endIndex
24      * @param reverse
25      */
26     public static void buildHeap(int[] data, int beginIndex, int endIndex, boolean reverse) {
27         if (beginIndex >= endIndex) {
28             return;
29         }
30         for (int i = (endIndex + beginIndex - 1) / 2; i >= beginIndex; i--) {
31             int cur = i;
32             if (reverse) {   //大顶堆,用来从小到大排序
33                 //发生交换之后需要检查孙子节点,重孙子节点...
34                 while (2 * cur + 1 <= endIndex) {
35                     int biggerChildIndex = 2 * cur + 1;
36                     if (biggerChildIndex + 1 <= endIndex) {
37                         if (data[biggerChildIndex] < data[biggerChildIndex + 1]) {
38                             biggerChildIndex = biggerChildIndex + 1;
39                         }
40                     }
41                     //找到最大子节点,如果比当前节点大,就交换
42                     if (data[i] < data[biggerChildIndex]) {
43                         int tmp = data[i];
44                         data[i] = data[biggerChildIndex];
45                         data[biggerChildIndex] = tmp;
46                         //准备检查孙子节点
47                         cur = biggerChildIndex;
48                     } else {
49                         break;
50                     }
51                 }
52             } else {    //小顶堆,用来从大到小排序
53                 //发生交换之后需要检查孙子节点,重孙子节点...
54                 while (2 * cur + 1 <= endIndex) {
55                     int samllerChildIndex = 2 * i + 1;
56                     if (samllerChildIndex + 1 <= endIndex) {
57                         if (data[samllerChildIndex] > data[samllerChildIndex + 1]) {
58                             samllerChildIndex = samllerChildIndex + 1;
59                         }
60                     }
61                     //找到最小子节点,如果比当前节点小,就交换
62                     if (data[i] > data[samllerChildIndex]) {
63                         int tmp = data[i];
64                         data[i] = data[samllerChildIndex];
65                         data[samllerChildIndex] = tmp;
66                         cur = samllerChildIndex;
67                     } else {
68                         break;
69                     }
70                 }
71             }
72         }
73     }

三、直接插入排序

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

 1 /**
 2      *  插入排序
 3      * @param data  要排序的数组
 4      * @param reverse 从大到小(false)还是从小到大(ture)
 5      */
 6     public static void sort(int[] data, boolean reverse) {
 7         if (data.length == 1) {
 8             return;
 9         }
10         int tmp = 0;
11         for (int i = 1; i < data.length; i++) {
12             tmp = data[i];
13             int n = i - 1;
14             for (; n >= 0; n--) {
15                 if (reverse) {   //从小到大排序
16                     if (data[n] >= tmp) {
17                         data[n + 1] = data[n];  //将大于当前值的数后移一个位置
18                     } else {
19                         break;
20                     }
21                 } else {    //从大到小排序
22                     if (data[n] <= tmp) {
23                         data[n + 1] = data[n];  //将小于当前值的数后移一个位置
24                     } else {
25                         break;
26                     }
27                 }
28             }
29             data[n+1] = tmp;
30         }
31     }

四、归并排序

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

 1  /**
 2      * 归并排序
 3      * @param data    要排序的数组
 4      * @param reverse 从大到小(false)还是从小到大(ture)
 5      */
 6     public static void sort(int[] data, int left, int right, boolean reverse) {
 7         if (left >= right) {
 8             return;
 9         }
10         int mid = (left + right) / 2;
11         sort(data, left, mid, reverse);
12         sort(data, mid + 1, right, reverse);
13         merge(data, left, mid, right, reverse);
14     }
15
16     /**
17      * 合并已排序好的两段
18      * @param data
19      * @param left
20      * @param mid
21      * @param right
22      * @param reverse
23      */
24     public static void merge(int[] data, int left, int mid, int right, boolean reverse) {
25         int[] tmp = new int[right - left + 1];
26         int i = left;
27         int j = mid + 1;
28         int n = 0;
29         while (i <= mid && j <= right) {
30             if (reverse) {  //从小到大
31                 if (data[i] <= data[j]) {
32                     tmp[n++] = data[i++];
33                 } else {
34                     tmp[n++] = data[j++];
35                 }
36             } else {    //从大到小
37                 if (data[i] <= data[j]) {
38                     tmp[n++] = data[j++];
39                 } else {
40                     tmp[n++] = data[i++];
41                 }
42             }
43         }
44         while (i <= mid) {
45             tmp[n++] = data[i++];
46         }
47         while (j <= right) {
48             tmp[n++] = data[j++];
49         }
50         for (int k = 0; k < tmp.length; k++) {
51             data[left + k] = tmp[k];
52         }
53     }

五、快递排序

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

 1    /**
 2      * 快速排序
 3      * @param data
 4      * @param left
 5      * @param right
 6      * @param reverse 从大到小(false)还是从小到大(ture)
 7      */
 8     public static void sort(int[] data, int left, int right, boolean reverse) {
 9         if (left >= right) {
10             return;
11         }
12         int index = getIndex(data, left, right, reverse);
13         sort(data, left, index - 1, reverse);
14         sort(data, index + 1, right, reverse);
15     }
16
17     /**
18      * 将待排序片段调整顺序,获得"中间数据"的正确索引
19      * @param data
20      * @param left
21      * @param right
22      * @param reverse 从大到小(false)还是从小到大(ture)
23      * @return
24      */
25     public static int getIndex(int[] data, int left, int right, boolean reverse) {
26         int cur = data[left];
27         int i = left;
28         int j = right;
29         while (i < j) {
30             if (reverse) {  //从小到大
31                 while (data[j] > cur && i < j) {
32                     --j;
33                 }
34                 data[i] = data[j];
35                 while (data[i] <= cur && i < j) {
36                     ++i;
37                 }
38                 data[j]=data[i];
39             } else {    //从大到小
40                 while (data[j] < cur && i < j) {
41                     --j;
42                 }
43                 data[i]=data[j];
44                 while (data[i] >= cur && i < j) {
45                     ++i;
46                 }
47                 data[j]=data[i];
48             }
49         }
50         data[i] = cur;
51         return i;
52     }

六、基数排序

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

 1     /**
 2      * 基数排序
 3      * @param data    要排序的数组
 4      * @param reverse 从大到小(false)还是从小到大(ture)
 5      */
 6     public static void sort(int[] data, boolean reverse) {
 7         if (data.length == 1) {
 8             return;
 9         }
10         int max = 0;
11         for (int i = 0; i < data.length; i++) { //找出最大的数据
12             if (max < data[i]) {
13                 max = data[i];
14             }
15         }
16         System.out.println("the max number is :" + max);
17         int radix = 1;
18         ArrayList<ArrayList<Integer>> numbers = new ArrayList<ArrayList<Integer>>(10);
19         for (int i = 0; i < 10; i++) {
20             numbers.add(i, new ArrayList<Integer>());
21         }
22         while (max > radix) {
23             for (int i = 0; i < data.length; i++) {
24                 int index = (data[i] / radix) % 10;
25                 ArrayList<Integer> list = numbers.get(index);
26                 list.add(data[i]);
27                 numbers.set(index, list);
28             }
29             resetOrder(data, numbers, reverse);
30             radix = radix * 10;
31         }
32     }
33
34     /**
35      * 重新调整数组顺序
36      * @param data
37      * @param numbers
38      * @param reverse 从大到小(false)还是从小到大(ture)
39      */
40     public static void resetOrder(int[] data, ArrayList<ArrayList<Integer>> numbers, boolean reverse) {
41         int n = 0;
42         if (reverse) {
43             for (int i = 0; i < numbers.size(); i++) {
44                 ArrayList<Integer> list = numbers.get(i);
45                 while(list.size()>0){
46                     data[n++] = list.get(0);
47                     list.remove(0);
48                 }
49             }
50         } else {
51             for (int i = numbers.size() - 1; i >= 0; i--) {
52                 ArrayList<Integer> list = numbers.get(i);
53                 while(list.size()>0){
54                     data[n++] = list.get(0);
55                     list.remove(0);
56                 }
57             }
58         }
59     }

七、选择排序

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

 1     /**
 2      * 选择排序
 3      * @param data  要排序的数组
 4      * @param reverse 从大到小(false)还是从小到大(ture)
 5      */
 6     public static void sort(int[] data, boolean reverse) {
 7         if (data.length == 1) {
 8             return;
 9         }
10         for(int i=0;i<data.length-1;i++){
11             int tmp=data[i];    //要初始化
12             int index = i;      //要初始化
13             for(int j=i;j<data.length;j++){
14                 if(reverse) {   //从小到大(ture)
15                     if (tmp>=data[j]){
16                         tmp = data[j];  //最小值
17                         index = j;
18                     }
19                 }else {
20                     if (tmp<=data[j]){
21                         tmp = data[j];  //最大值
22                         index = j;
23                     }
24                 }
25             }
26             data[index] = data[i];
27             data[i] = tmp;
28         }
29     }

八、希尔排序

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

 1     /**
 2      * 希尔排序
 3      * @param data    要排序的数组
 4      * @param reverse 从大到小(false)还是从小到大(ture)
 5      */
 6     public static void sort(int[] data, boolean reverse) {
 7         if (data.length == 1) {
 8             return;
 9         }
10         for (int d = data.length / 2; d >= 1; d = d / 2) {  //组大小
11             for (int k = 0; k < d; k++) {   //多少组
12                 for (int n = d + k; n < data.length; n = n + d) {   //同一组
13                     int cur = n;
14                     while (cur - d >= 0) {  //插入排序
15                         int tmp = 0;
16                         if (reverse) {  //小到大(ture)
17                             if (data[cur] <= data[cur - d]) {
18                                 tmp = data[cur];
19                                 data[cur] = data[cur - d];
20                                 data[cur - d] = tmp;
21                             }
22                         } else {         //从大到小(false)
23                             if (data[cur] >= data[cur - d]) {
24                                 tmp = data[cur];
25                                 data[cur] = data[cur - d];
26                                 data[cur - d] = tmp;
27                             }
28                         }
29                         cur = cur - d;
30                     }
31                 }
32             }
33         }
34
35     }

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

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

参考:

  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

就当自己回顾知识了

  

时间: 2024-08-26 03:03:01

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

Java千百问_04异常处理(007)_常见的java异常有哪些(非运行时)

点击进入_更多_Java千百问 1.常见的java运行时异常有哪些 了解非运行时异常看这里:什么是java中的异常 常见的运行时异常看这里:常见的运行时异常有哪些 我们所说的常见异常是jdk或者其他常用第三方jar中的异常,出现频次很高的异常.常见的非运行时异常(即检查异常,checked exception)包括: 操作数据库异常:SQLException 输入输出异常:IOException 文件未找到异常:FileNotFoundException 反射操作异常:ReflectiveOpe

【转载】20道常见初级Java面试题

这篇文章的内容很不错.学到了很多东西.值得仔细琢磨. http://mt.sohu.com/20160831/n466900239.shtml 20道常见初级Java面试题,入职者必备! 广州华信智原2016-08-31 09:30:37阅读(564)评论(0) 声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场.举报 大家都应该知道Java是目前最火的计算机语言之一,连续几年蝉联最受程序员欢迎的计算机语言榜首,因此每年新入职Java程序员也数不胜数.究

数学建模学习笔记(八大常见建模问题总结)

八大常见建模问题 1.    线性规划问题: 简称LP问题,使用单纯刑法进行求解. 如:如何利用现有资源来安排生产,以取得最大经济效益的问题 2.    整数规划 与线性规划类似,分支定界法求解. 3.    非线性规划 如投资类型的0-1规划问题: 4.    动态规划 动态规划(dynamicprogramming)是运筹学的一个分支,是求解多阶段决策问题的最优化方法. 如:最短路等,重在状态的描述,与状态转移方程的列举. 以丰富的想象力去建立模型,用创造性的技巧去求解. 5.    图与网

常见的 java错误

生产过程中出现的问题正逐渐得到中层和最高管理层的重视.不管是身为开发人员还是架构师,下列的事项都应该得到你足够的重视以避免陷入未来的尴尬境地.你也可以把它作为排查问题的便签 测试中使用的数据集规模不合适.比如,生产过程中一个典型的场景就是只使用 1 到 3 个账户进行测试,而这个数量本应是 1000 到 2000 个的.在做性能测试时,使用的数据必须是真实并且未经裁剪的.不贴近真实环境的性能测试,可能会带来不可预料的性能.拓展和多线程问题.只有使用更大规模的数据集对应用程序进行测试,才能保证它正

5个最常见的Java语言特点汇总,帮你更好学好Java!

作为编程届的常青树,Java常年盘踞在语言榜第一的位置,从业人员薪资待遇也普遍不错.目前,Java应用广泛,Java就业前景良好!虽然Java人才的薪水很高,但是对该类人才需求旺盛的IT企业却很难招聘倒合格的Java人才.在开发领域,Java培训成为了许多人的首选!最后,如果大家如果在自学遇到困难,想找一个java的学习环境,可以加入我们的java学习圈,点击我加入吧,会节约很多时间,减少很多在学习中遇到的难题. 对于零基础学员来说,想要学好Java,首先要先了解这个语言的编程特点.今天小编就给

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

上一篇:最常见的Java面试题及答案汇总(一) 容器 18. java 容器都有哪些? 常用容器的图录: 19. Collection 和 Collections 有什么区别? java.util.Collection 是一个集合接口(集合类的一个顶级接口).它提供了对集合对象进行基本操作的通用接口方法.Collection接口在Java 类库中有很多具体的实现.Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set. Collections

Java 实现常见内排序

一.内排序 1.排序基本概念 (1)什么是排序? 排序指将一个数据元素集合或者序列 按照某种规则 重新排列成一个 有序的集合或者序列.分为内排序.外排序.排序算法的好坏直接影响程序的执行速度以及存储空间的占有量. (2)什么是内排序?外排序? 内排序:指待排序的序列完全存放在内存中所进行的排序过程(不适合大量数据排序). 外排序:指大数据的排序,待排序的数据无法一次性读取到内存中,内存与外存需进行多次数据交换,以达到排序的目的. (3)什么是稳定排序? 稳定排序指的是 相等的数据经过某种排序算法

八大排序算法Java(转)

目录(?)[-] 概述 插入排序直接插入排序Straight Insertion Sort 插入排序希尔排序Shells Sort 选择排序简单选择排序Simple Selection Sort 选择排序堆排序Heap Sort 交换排序冒泡排序Bubble Sort 交换排序快速排序Quick Sort 归并排序Merge Sort 桶排序基数排序Radix Sort 总结 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序

常见的Java面试题整理

面试是我们每个人都要经历的事情,大部分人且不止一次,这里给大家总结常见的面试题,让大家在找工作时候能够事半功倍. 1 Switch能否用string做参数? a.在 Java 7 之前, switch 只能支持byte,short,char,int 或者其对应的封装类以及 Enum 类型.在JAVA 7中,String 支持被加上了. 2 equals与==的区别: a.==是判断两个变量或实例是不是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是不是相同 3 Obje