这几天一直在看严蔚敏老师的那本《数据结构》那本书。之前第一次学懵懵逼逼,当再次看的时候,发觉写的是非常详细,非常的好。

那就把相关的排序算法用我熟悉的Java语言记录下来了。以下排序算法是我认为比较重要的,而且在面试中比较容易考的算法。

  • 冒泡排序
  • 快速排序
  • 堆排序
  • 归并排序

(一)前言

排序其实是一个相当大的概念,主要分为两类:内部排序和外部排序。而我们通常所说的各种排序算法其实指的是内部排序算法。内部排序是基于内存的,整个排序过程都是在内存中完成的,而外部排序指的是由于数据量太大,内存不能完全容纳,排序的时候需要借助外存才能完成(常常是算计着某一部分已经计算过的数据移出内存让另一部分未被计算的数据进入内存)。而我们本篇文章将主要介绍内排序中的几种常用排序算法:

(二)冒泡排序

最经典的排序方法,没有之一,所有人学排序的第一个算法。

比较简单直接看代码吧。

  1. public class Main {
  2. public static void main(String[] args) {
  3.  
  4. int[] a = {7, 6, 9, 3, 2, 11, 9};
  5. Bubble b = new Bubble();
  6. b.bubbleSort(a);
  7. for (int i = 0; i < a.length; i++) {
  8. System.out.print(a[i] + " ");
  9. }
  10. System.out.println();
  11. }
  12. }
  13.  
  14. class Bubble {
  15.  
  16. int[] bubbleSort(int[] a) {
  17. for (int i = 0; i < a.length - 1; i++) {
  18. for (int j = i + 1; j < a.length; j++) {
  19. if (a[i] > a[j]) {
  20. swap(a, i, j);
  21. }
  22. }
  23. }
  24. return a;
  25. }
  26.  
  27. void swap(int[] a, int i, int j) {
  28. int t = 0;
  29. t = a[i];
  30. a[i] = a[j];
  31. a[j] = t;
  32. }
  33. }

(三)快速排序

史上最快的排序算法之一,称为快速排序。连Arrays.sort底层都是快速排序,不过有进行改进(DualPivotQuicksort三千多行代码,向大神跪了)

快速排序的基本思想是,从序列中任选一个元素,但通常会直接选择序列的第一个元素作为一个标准,所有比该元素值小的元素全部移动到他的左边,比他大的都移动到他的右边。我们称这叫做一趟快速排序,位于该元素两边的子表继续进行快速排序算法直到整个序列都有序。该排序算法是目前为止,内部排序中效率最高的排序算法。具体它是怎么做的呢?

首先他定义了两个头尾指针,分别指向序列的头部和尾部。从high指针位置开始扫描整个序列,如果high指针所指向的元素值大于等于临界值,指针前移。如果high指针所指向的元素的值小于临界值的话:

将high指针所指向的较小的值交换给low指针所指向的元素值,然后low指针前移。

然后重复上述过程,直至x=48左边全部小于他,右边全部大于他。看代码

  1. class Quick {
  2.  
  3. int[] quickSort(int[] a, int left, int right) {
  4.  
  5. if (left < right) {
  6. int pos = postion(a, left, right);
  7. quickSort(a, left, pos - 1);
  8. quickSort(a, pos + 1, right);
  9. }
  10. return a;
  11. }
  12.  
  13. int postion(int[] a, int left, int right) {
  14.  
  15. int t = a[left];
  16. while (left < right) {
  17. while (left < right && t <= a[right]) --right;
  18. a[left] = a[right];
  19. while (left < right && t >= a[left]) ++left;
  20. a[right] = a[left];
  21. }
  22. a[left] = t;
  23. return left;
  24. }
  25.  
  26. }

(四)堆排序

先了解下什么叫做堆。

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。

大根堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]  

小根堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]  

同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子

堆排序我自认为理解了,但写起博客有些麻烦,大家想要了解可以去 这里看看  堆排序算法,我觉的写的挺好的

我这里直接用PriorityQueue

  1. class Heap {
  2.  
  3. int[] heapSort(int[] a) {
  4.  
  5. int[] t = new int[a.length];
  6. PriorityQueue<Integer> pq = new PriorityQueue<>(a.length);
  7. //建堆
  8. for (int i = 0; i < a.length; i++) {
  9. pq.add(a[i]);
  10. }
  11. int cnt = 0;
  12. //出堆后破坏了堆的定义,那就调整堆
  13. while (!pq.isEmpty()) {
  14. t[cnt++] = pq.poll();
  15. }
  16. return t;
  17. }
  18. }

(五)归并排序

这里的归并类排序算法指的就是归并排序。归并排序的核心思想是,对于一个初始的序列不断递归,直到子序列中的元素足够少时,对他们进行直接排序。然后递归返回继续对两个分别有序的序列进行直接排序,最终递归结束的时候,整个序列必然是有序的。就是分而治之

  1. /*归并排序的递归调用*/
  2. public static void MergeSort(int[] array,int low,int high){
  3. if(low == high){
  4. //说明子数组长度为1,无需分解,直接返回即可
  5. }else{
  6. int p = (low+high)/2;
  7. MergeSort(array,low,p);
  8. MergeSort(array,p+1,high);
  9. //完成相邻两个子集合的归并
  10. MergeTwoData(array,low,high);
  11. }
  12. }
  13. /*用于排序两个子序列的归并排序算法实现*/
  14. public static void MergeTwoData(int[] array,int low,int high){
  15. int[] arrCopy = new int[high-low+1];
  16. int i,j;
  17. i = low;j= (low+high)/2+1;
  18. for (int key=0;key<=high-low;key++){
  19. //如果左边子数组长度小于右边数组长度,当左数组全部入库之后,右侧数组不用做比较直接入库
  20. if(i==(low+high)/2+1){
  21. arrCopy[key] = array[j];
  22. j++;
  23. }
  24. //如果右侧数组长度小于左侧数组长度,当右侧数组全部入库之后,左侧数组不用做比较直接入库
  25. else if(j==high+1){
  26. arrCopy[key]=array[i];
  27. i++;
  28. }else if(array[i]<array[j]){
  29. arrCopy[key]=array[i];
  30. i++;
  31. }else{
  32. arrCopy[key] = array[j];
  33. j++;
  34. }
  35. }
  36. j = 0;
  37. //按顺序写回原数组
  38. for(int x=low;x<=high;x++) {
  39. array[x] = arrCopy[j];
  40. j++;
  41. }
  42. }

排序算法(Java实现)的更多相关文章

  1. 八大排序算法Java

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

  2. 八大排序算法Java实现

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

  3. 6种基础排序算法java源码+图文解析[面试宝典]

    一.概述 作为一个合格的程序员,算法是必备技能,特此总结6大基础算法.java版强烈推荐<算法第四版>非常适合入手,所有算法网上可以找到源码下载. PS:本文讲解算法分三步:1.思想2.图 ...

  4. 排序算法Java版,以及各自的复杂度,以及由堆排序产生的top K问题

    常用的排序算法包括: 冒泡排序:每次在无序队列里将相邻两个数依次进行比较,将小数调换到前面, 逐次比较,直至将最大的数移到最后.最将剩下的N-1个数继续比较,将次大数移至倒数第二.依此规律,直至比较结 ...

  5. 九大排序算法Java实现

    之前学习数据结构与算法时花了三天时间整理九大排序算法,并采用Java语言来实现,今天第一次写博客,刚好可以把这些东西从总结的文档中拿出来与大家分享一下,同时作为自己以后的备忘录. 1.排序算法时间复杂 ...

  6. 排序系列 之 希尔排序算法 —— Java实现

    基本思想: 希尔排序的实质就是分组插入排序,又称缩小增量法. 将整个无序序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本 ...

  7. 十大基础排序算法[java源码+动静双图解析+性能分析]

    一.概述 作为一个合格的程序员,算法是必备技能,特此总结十大基础排序算法.java版源码实现,强烈推荐<算法第四版>非常适合入手,所有算法网上可以找到源码下载. PS:本文讲解算法分三步: ...

  8. 排序算法Java代码实现(一)—— 选择排序

    以下几篇随笔都是记录的我实现八大排序的代码,主要是贴出代码吧,讲解什么的都没有,主要是为了方便我自己复习,哈哈,如果看不明白,也不要说我坑哦! 本片分为两部分代码: 常用方法封装 排序算法里需要频繁使 ...

  9. 【排序算法】希尔排序算法 Java实现

    希尔排序算法是按其设计者希尔(Donald Shell)的名字命名,该算法由1959年公布,是插入排序的一种更高效的改进版本. 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎 ...

随机推荐

  1. Mysql Order By 字符串排序,mysql 字符串order by

    Mysql Order By 字符串排序,mysql 字符串order by ============================== ©Copyright 蕃薯耀 2017年9月30日 http ...

  2. 分析业务模型-类图(Class Diagram)

    分析业务模型-类图(Class Diagram)     分析业务模型-类图(Class Diagram)(上) 摘要:类图(Class Diagram)可能是用得最多的一种UML图.类图的基本语法并 ...

  3. C#编译成以管理员身份运行程序

    转载自:http://www.cnblogs.com/babycool/p/3569183.html 在使用winform程序获取调用cmd命令提示符时,如果是win7以上的操作系统,会需要必须以管理 ...

  4. (1-1)SpringCloud-Eureka:服务的注册与发现

    SpringCloud Eureka是SpringCloud Netflix服务套件中的一部分,它基于Netflix Eureka做了二次封装,主要负责完成微服务架构中的服务治理功能.下面来做一个示例 ...

  5. 转-python中的闭包

    出处:http://www.cnblogs.com/ma6174/archive/2013/04/15/3022548.html 记录下 简单说,闭包就是根据不同的配置信息得到不同的结果 再来看看专业 ...

  6. junit源码解析--核心类

    JUnit 的概念及用途 JUnit 是由 Erich Gamma 和 Kent Beck 编写的一个开源的单元测试框架.它属于白盒测试,只要将待测类继承 TestCase 类,就可以利用 JUnit ...

  7. JAVA中double类型运算结果异常的解决

    问题: 对两个double类型的值进行运算,有时会出现结果值异常的问题.比如: System.out.println(19.99+20); System.out.println(1.0-0.66); ...

  8. JVM类加载机制---类加载的过程

    一.类加载的时机 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用.卸载 7个阶段,其中验证.准备.解析 3个部分统称为 连接. 二.具体步骤 ...

  9. ABAP更换请求

    当创建的程序或表操作失误存储在其他的请求下边如何更换请求呢? 事务代码:SE09 双击请求号,复制存储错误的对象 打开一个新窗口,双击正确的请求,点击修改,将复制的对象粘贴在正确的请求下 将错误的请求 ...

  10. git stash暂存文件

    git stash 可用来暂存当前正在进行的工作, 比如想pull 最新代码,但又不想提交代码.先git stash暂存,pull之后,用git stash pop或者git stash apply取 ...