Java常用的排序算法

转载自博客http://blog.csdn.net/xsf50717

排序算法

重要性不言而喻,很多算法问题往往选择一个好的排序算法往往问题可以迎刃而解

1、冒泡算法

冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。也就是双重循环就可以搞定的问题但是需要注意下一边界

算法步骤:

1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。

2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

3)针对所有的元素重复以上的步骤,除了最后一个。

4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

[java] view plain copy

  1. <span style="font-family:Microsoft YaHei;font-size:14px;">public void BubbleSort(int[] a) {
  2. int temp = 0;
  3. int len = a.length;
  4. for (int i = 0; i < len; i++) {
  5. for (int j = 1; j < len - i; j++)
  6. if (a[j - 1] > a[j]) {
  7. //注意分清是a[j-1]还是a[j]不然容易出现边界问题
  8. // 从小到大排序
  9. temp = a[j - 1];
  10. a[j - 1] = a[j];
  11. a[j] = temp;
  12. }
  13. }
  14. }</span>

优化的冒泡排序

由于可能在前几次就已经排好序,但是在上一种冒泡排序中仍然需要一直遍历到最后。

优化措施:设置一个标志,如果这一趟发生了交换,则为true,否则为false。明显如果有一趟没有发生交换,说明排序已经完成。

[java] view plain copy

  1. <span style="font-family:Microsoft YaHei;font-size:14px;">public void BubbleSort1(int[] a) {
  2. int temp = 0;
  3. int len = a.length;
  4. boolean flag = true;
  5. while (flag) {
  6. flag = false;
  7. for (int j = 1; j < len - 1; j++)
  8. if (a[j - 1] > a[j]) {
  9. // 注意分清是a[j-1]还是a[j]不然容易出现边界问题
  10. // 从小到大排序
  11. temp = a[j - 1];
  12. a[j - 1] = a[j];
  13. a[j] = temp;
  14. // 设置标志位
  15. flag = true;
  16. }
  17. }
  18. }</span>

2、快速排序

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

算法步骤:
1) 从数列中挑出一个元素,称为 “基准”(pivot),
2 )重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
3 )递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

[java] view plain copy

  1. <span style="font-family:Microsoft YaHei;font-size:14px;">    private static void quick_sort(int[] arr, int low, int high) {
  2. // 解决和合并
  3. if (low <= high) {
  4. int mid = partition(arr, low, high);
  5. // 递归
  6. quick_sort(arr, low, mid - 1);
  7. quick_sort(arr, mid + 1, high);
  8. }
  9. }
  10. private static int partition(int[] arr, int low, int high) {
  11. // 分解
  12. int pivot = arr[high];
  13. int i = low - 1;
  14. int temp;
  15. for (int j = low; j < high; j++) {
  16. if (arr[j] < pivot) {
  17. i++;
  18. temp = arr[i];
  19. arr[i] = arr[j];
  20. arr[j] = temp;
  21. }
  22. }
  23. // 交换中间元素和privot
  24. temp = arr[i + 1];
  25. arr[i + 1] = arr[high];
  26. arr[high] = temp;
  27. return i + 1;
  28. }</span>

3、归并排序

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

算法步骤:

1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置

3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

4. 重复步骤3直到某一指针达到序列尾

5. 将另一序列剩下的所有元素直接复制到合并序列尾

[java] view plain copy

  1. <span style="font-family:Microsoft YaHei;font-size:14px;">  public static int[] sort(int[] nums, int low, int high) {
  2. int mid = (low + high) / 2;
  3. if (low < high) {
  4. // 左边
  5. sort(nums, low, mid);
  6. // 右边
  7. sort(nums, mid + 1, high);
  8. // 左右归并
  9. merge(nums, low, mid, high);
  10. }
  11. return nums;
  12. }
  13. public static void merge(int[] nums, int low, int mid, int high) {
  14. int[] temp = new int[high - low + 1];
  15. int i = low;// 左指针
  16. int j = mid + 1;// 右指针
  17. int k = 0;
  18. // 把较小的数先移到新数组中
  19. while (i <= mid && j <= high) {
  20. if (nums[i] < nums[j]) {
  21. temp[k++] = nums[i++];
  22. } else {
  23. temp[k++] = nums[j++];
  24. }
  25. }
  26. // 把左边剩余的数移入数组
  27. while (i <= mid) {
  28. temp[k++] = nums[i++];
  29. }
  30. // 把右边边剩余的数移入数组
  31. while (j <= high) {
  32. temp[k++] = nums[j++];
  33. }
  34. // 把新数组中的数覆盖nums数组
  35. for (int k2 = 0; k2 < temp.length; k2++) {
  36. nums[k2 + low] = temp[k2];
  37. }
  38. }  </span>

4、选择排序

选择排序(Selection sort)也是一种简单直观的排序算法。
算法步骤:
1)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
2)再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
3)重复第二步,直到所有元素均排序完毕。

[java] view plain copy

  1. <span style="font-family:Microsoft YaHei;font-size:14px;">  public int[] ChoseSort(int[] intArr){
  2. for(int i=0;i<intArr.length;i++){
  3. int lowIndex = i;
  4. for(int j=i+1;j<intArr.length;j++){
  5. if(intArr[j]<intArr[lowIndex]){
  6. lowIndex = j;
  7. }
  8. }
  9. //将当前第一个元素与它后面序列中的最小的一个 元素交换,也就是将最小的元素放在最前端
  10. int temp = intArr[i];
  11. intArr[i] = intArr[lowIndex];
  12. intArr[lowIndex] = temp;
  13. }
  14. return intArr;
  15. } </span>

5、堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
堆排序的平均时间复杂度为Ο(nlogn) 。
算法步骤:
1)创建一个堆H[0..n-1]
2)把堆首(最大值)和堆尾互换
3)把堆的尺寸缩小1,并调用shift_down(0),目的是把新的数组顶端数据调整到相应位置
4) 重复步骤2,直到堆的尺寸为1

调整堆部分不太好写建议参考http://blog.csdn.net/jdream314/article/details/6634863

最后给出一张各算法的性能比较图

时间: 2024-10-23 01:30:23

Java常用的排序算法的相关文章

Java 常用的排序算法【选择、冒泡、快排】

选择排序: 简述:从数组的第一个元素开始,依次与其他所有的元素对比,如果比自身大或小(取决于升序或降序)交换位置. ChiceSort Code 冒泡排序: 简述:比较数组中两个相邻的元素,如果前者比较大则交换位置.像啤酒杯中的气泡一样,先漂上来最大的气泡,再漂上来第二大的气泡......... BubbleSort Code 快速排序: 简述:寻找一个基准(数组中的第一个或最后一个),表的两端同时向中间扫描,小在左,大在右.然后分别从基准两边进行递归排序. QuickSortCode 原文地址

Java常用三种算法排序比较

Java常用三种算法排序比较 冒泡排序: package demo1; /** * * @author xiaoye 2014-5-13 */ /** * 有N 个数据需要排序,则从第0 个数开始,依次比较第0 和第1 个数据, * 如果第0 个大于第1 个则两者交换,否则什么动作都不做,继续比较第 1 个第2个-, * 这样依次类推,直至所有数据都"冒泡"到数据顶上. 冒泡排序的效率 O(N*N ),比较 N*N/2 ,交换N*N/4 . */ public class Bubble

java SE 常用的排序算法

java程序员会用到的经典排序算法实现 常用的排序算法(以下代码包含的)有以下五类: A.插入排序(直接插入排序.希尔排序) B.交换排序(冒泡排序.快速排序) C.选择排序(直接选择排序.堆排序) D.归并排序 E.分配排序(基数排序) 以下算法都是可以实现的,但是什么情况使用什么算法都是根据实际情况选用的. 如果有用的话就顶起吧,谢谢. import java.util.ArrayList; import java.util.List; public class Sort { // test

JavaScript实现常用的排序算法

▓▓▓▓▓▓ 大致介绍 由于最近要考试复习,所以学习js的时间少了 -_-||,考试完还会继续的努力学习,这次用原生的JavaScript实现以前学习的常用的排序算法,有冒泡排序.快速排序.直接插入排序.希尔排序.直接选择排序 ▓▓▓▓▓▓ 交换排序 交换排序是一类在排序过程中借助于交换操作来完成排序的方法,基本思想是两两比较排序记录的关键字,如果发现两个关键字逆序,则将两个记录位置互换,重复此过程,直到该排序列中所有关键字都有序为止,接下来介绍交换排序中常见的冒泡排序和快速排序 ▓▓▓▓▓▓

【计算机基础】 常用的排序算法的时间复杂度和空间复杂度

常用的排序算法的时间复杂度和空间复杂度 排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O(n2) O(n2) 稳定 O(1) 快速排序 O(n2) O(n*log2n) 不稳定 O(log2n)~O(n) 选择排序 O(n2) O(n2) 稳定 O(1) 二叉树排序 O(n2) O(n*log2n) 不一顶 O(n) 插入排序 O(n2) O(n2) 稳定 O(1) 堆排序 O(n*log2n) O(n*log2n) 不稳定 O(1) 希尔排序 O O 不稳定 O(1) 1

7 种常用的排序算法-视觉直观感受

7 种常用的排序算法-可视化 1. 快速排序 介绍: 快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来,且在大部分真实世界的数据,可以决定设计的选择,减少所需时间的二次方项之可能性. 步骤: 从数列中挑出一个元素,称为 “基准”(pivot),

Java中各种排序算法

//插入排序:package org.rut.util.algorithm.support; import org.rut.util.algorithm.SortUtil;/** * @author treeroot * @since 2006-2-2 * @version 1.0 */public class InsertSort implements SortUtil.Sort{ /** (non-Javadoc) * @see org.rut.util.algorithm.SortUtil

几种常用的排序算法总结

主要针对于插入排序,交换(冒泡和快速),选择,堆排序,归并这几种排序的基本原理和时间复杂度,及空间复杂度的一个总结. 一.插入排序 基本执行过程:3  5  2  7  9  8 1.从小到大:从第二个数开始,每次比较都与前边的几个数进行比较 但是从大到小,要先与前边排好序的几个数中的最大的开始进行比较即倒序比较,依次往前推. 如:5 先与3进行比较,比3大,所以直接排在3的后边为:3 5: 2要先与5进行比较,比5小,再与3比较,比3小,所以排序后为 2 3 5: 7要先与5比,比5大,所以直

Java中冒牌排序算法

冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面. 即首先比较第1个和第2个数,将小数放前,大数放后.然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后.重复以上过程,仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到最大数前的一对相邻数,将小数放前,大数放后,第二趟结束,在倒数第二个数中得到一个新的最大数.如此下去,直至最终