排序算法(java版)

1. 冒泡算法
2. 快速排序
3. 归并排序
4. 选择排序
5. 堆排序

排序算法

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

1、冒泡算法

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

算法步骤:

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

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

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

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

 1 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 }

优化的冒泡排序

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

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

 1 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 }

 2、快速排序

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

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

算法步骤:

1) 从数列中挑出一个元素,称为 “基准”(pivot)

2 )重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

3 )递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

 1 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 }
11
12 private static int partition(int[] arr, int low, int high) {
13     // 分解
14     int pivot = arr[high];
15     int i = low - 1;
16     int temp;
17     for (int j = low; j < high; j++) {
18
19         if (arr[j] < pivot) {
20             i++;
21             temp = arr[i];
22             arr[i] = arr[j];
23             arr[j] = temp;
24         }
25     }
26     // 交换中间元素和privot
27     temp = arr[i + 1];
28     arr[i + 1] = arr[high];
29     arr[high] = temp;
30     return i + 1;
31
32 }

3、归并排序

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

算法步骤:

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

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

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

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

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

 1 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
14 public static void merge(int[] nums, int low, int mid, int high) {
15     int[] temp = new int[high - low + 1];
16     int i = low;// 左指针
17     int j = mid + 1;// 右指针
18     int k = 0;
19
20     // 把较小的数先移到新数组中
21     while (i <= mid && j <= high) {
22         if (nums[i] < nums[j]) {
23             temp[k++] = nums[i++];
24         } else {
25             temp[k++] = nums[j++];
26         }
27     }
28
29     // 把左边剩余的数移入数组
30     while (i <= mid) {
31         temp[k++] = nums[i++];
32     }
33
34     // 把右边边剩余的数移入数组
35     while (j <= high) {
36         temp[k++] = nums[j++];
37     }
38
39     // 把新数组中的数覆盖nums数组
40     for (int k2 = 0; k2 < temp.length; k2++) {
41         nums[k2 + low] = temp[k2];
42     }
43 }

4、选择排序

选择排序(Selection sort)也是一种简单直观的排序算法。

算法步骤:

1)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置

2)再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

3)重复第二步,直到所有元素均排序完毕。

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

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
最后给出一张各算法的性能比较图

参考:http://www.cricode.com/3212.html

http://blog.csdn.net/morewindows/article/details/7961256

时间: 2024-12-28 17:54:57

排序算法(java版)的相关文章

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

常用的排序算法包括: 冒泡排序:每次在无序队列里将相邻两个数依次进行比较,将小数调换到前面, 逐次比较,直至将最大的数移到最后.最将剩下的N-1个数继续比较,将次大数移至倒数第二.依此规律,直至比较结束.时间复杂度:O(n^2) 选择排序:每次在无序队列中"选择"出最大值,放到有序队列的最后,并从无序队列中去除该值(具体实现略有区别).时间复杂度:O(n^2) 直接插入排序:始终定义第一个元素为有序的,将元素逐个插入到有序排列之中,其特点是要不断的 移动数据,空出一个适当的位置,把待插

常见的排序算法--java版

个人总结的常见的排序算法 public class Sort { // 1.冒泡:稳定,最优O(n) 最差O(n^2) 平均O(n^2) private static void sort1(int[] arr) { for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length - 1; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = ar

扎金花大小比较算法(Java版)

注:以下算法说明仅限一副牌(不包含大小王)的情况 1.扎金花规则说明(大家都懂的,这里做简单描述): 1)玩家每人3张牌: 2)牌面大小2.3.4.5.6.7.8.9.10(用T表示),J.Q.K.A,大小依次递增: 3)牌的花色有黑桃(用H表示).红心(用X表示).梅花(用M表示).方块(用F表示),大小依次递减: 4)牌有豹子(3张牌数字大小相同).同花顺.同花(此种未实现,有兴趣的玩家可以自己加上,或者欢迎和我交流).顺子.对子.散牌几种类型,大小依次递减: 5)玩家先比牌的类型,如先按照

数据结构排序算法Java实现

闲的无聊又拿起了大学的数据结构的书看起来 <数据结构(c语言版)>严蔚敏 吴伟民编著. 里面有几个排序算法,感觉挺好玩的,就想着写出来玩玩. package test.sort; /** * @Title: TODO * @Description: TODO * @author: * @date: 2014-8-10 上午11:20:43 * */ public class quickSort { private static int datas[] = {23,42,12,45,56,63,

排序算法Java实现

排序算法Java实现 排序算法的分类: 内部排序,在排序过程中,全部记录放在内存中,称为内部排序: 外部排序,在排序过程中需要使用外部存储(磁盘),则称为外部排序. 主要介绍内部排序: 插入排序:直接插入排序.二分法插入排序.希尔排序 选择排序:简单选择排序.堆排序 交换排序:冒泡排序.快速排序 归并排序 基数排序 插入排序 直接插入排序 基本思想:对于给定的一组记录,初始时假设第一个记录自成一个有序序列,其余记录为无序序列.接着从第二个记录开始,按照记录的大小依次将当前处理的记录插入到其之前的

MapReduce原理——PageRank算法Java版

Page Rank就是MapReduce的来源,下文是一个简单的计算PageRank的示例. import java.text.DecimalFormat; /**  * Created by jinsong.sun on 2014/7/15.  */ public class PageRankCaculator {     public static void main(String[] args) {         double[][] g = calcG(genS(), 0.85);  

经典排序算法(Java实现)

以下程序均将数据封装于DataWrap数据包装类中,如下所示: 1 //数据包装类 2 class DataWrap implements Comparable<DataWrap> 3 { 4 int data; 5 String flag; 6 public DataWrap(int data,String flag) 7 { 8 this.data = data; 9 this.flag = flag; 10 } 11 //重写compareTo方法 12 public int compa

八大排序算法JAVA实现(时间复杂度O(n*logn)篇)

本文讲述时间复杂度为n*logn的排序算法:归并排序.快速排序.堆排序以及希尔排序的原理.Java实现以及变形应用. 一.归并排序 原理:把两个有序数列合并为一个有序数列.需递归实现. Java实现: 1 public int[] mergeSort(int[] a, int n) 2 { 3 return doMergeSort(a, n, 0, n - 1); 4 } 5 public int[] doMergeSort(int[] a, int n, int start, int end)

高速排序(Java版)

package com.love.test; import java.util.Scanner; /** * @author huowolf *高速排序实现 *快排是十分优秀的排序算法. *核心:分治法(1.选基元2.分区3.递归子列) */ public class QuickSort { public static void quickSort(int[] arr,int start ,int end) { if(start<end) { int i=start, j=end, x=arr[

九大排序算法Java实现

之前学习数据结构与算法时花了三天时间整理九大排序算法,并采用Java语言来实现,今天第一次写博客,刚好可以把这些东西从总结的文档中拿出来与大家分享一下,同时作为自己以后的备忘录. 1.排序算法时间复杂度.稳定性分类: 2.排序算法问题描述与实现 2.1冒泡排序(交换排序-稳定) [问题描述]对于一个int数组,请编写一个冒泡排序算法,对数组元素排序. 问题分析:冒泡排序,顾名思义,从前往后遍历,每次遍历在末尾固定一个最大值. 易错点:每次内层循环结束都会在末尾确定一个元素的位置,因此内层循环的判