七大排序算法分析及java实现

知识点:

排序分为内排序和外排序。内排序是在排序整个过程中,待排序的所有记录全部被放置在内存中。外排序是由于排序的记录个数太多,不能同时放置在内存,整个排序过程需要在内外存之间多次交换数据才能进行。这里主要介绍内排序:



内排序可分为四种,交换排序、选择排序、插入排序、归并排序。

交换排序 选择排序 插入排序 归并排序
冒泡排序 快速排序 简单选择排序 堆排序 简单插入排序 shell排序 归并排序


排序的稳定性:

若k为记录的排序字段且ki=kj,排序前ki所表示的记录排在kj所表示的记录前面,排序后若顺序保持不变,则为稳定排序,若排序后ki,kj顺序发生变化,则为不稳定排序。



七种排序算法性能归纳比较:

1、冒泡排序

 1 public class BubbleSort {
 2
 3     public static void main(String[] args) {
 4         int[] array = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
 5         bubbleSort(array);
 6         System.out.println(Arrays.toString(array));
 7     }
 8
 9     public static void bubbleSort(int[] array) {
10         boolean flag = true;
11         for(int i = 0; i < array.length - 1 && flag; i++) {
12             flag = false;
13             for(int j = array.length - 1; j > i; j--) {
14                 if(array[j] < array[j - 1]) {
15                     swap(array, j, j - 1);
16                     flag = true;
17                 }
18             }
19         }
20     }
21
22     public static void swap(int[] array, int m, int n) {
23         int temp = array[m];
24         array[m] = array[n];
25         array[n] = temp;
26     }
27 }

最好情况下(待排序表顺序),进行n-1次比较,没有交换,时间复杂度为O(n)

最坏情况下(待排序表逆序),比较和交换次数相等,为1+2+3+……+(n-1) = n*(n-1)/2,时间复杂度为O(n2)

2、简单选择排序

 1 public class SelectSort {
 2     public static void main(String[] args) {
 3         int[] array = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
 4         selectSort(array);
 5         System.out.println(Arrays.toString(array));
 6     }
 7
 8     public static void selectSort(int[] array) {
 9         for(int i = 0; i < array.length -1; i++) {
10             int min = i;
11             for(int j = i + 1; j < array.length; j++) {
12                 if(array[min] > array[j]) {
13                     min = j;
14                 }
15             }
16             if(min != i) {
17                 int temp = array[min];
18                 array[min] = array[i];
19                 array[i] = temp;
20             }
21         }
22     }
23
24     public static void swap(int[] array, int m, int n) {
25         int temp = array[m];
26         array[m] = array[n];
27         array[n] = temp;
28     }
29 }

特点:交换次数少

无论最好最坏情况,比较1+2+3+……+(n-1)+(n-2)=n*(n+1)/2次,时间复杂度O(n2)

最好情况下交换0次,最差情况下交换n-1次

尽管与冒泡排序时间复杂度同为O(n2),但其性能略优于冒泡排序

3、直接插入排序

 1 public class InsertSort {
 2
 3     public static void main(String[] args) {
 4         int[] array = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
 5         insertSort(array);
 6         System.out.println(Arrays.toString(array));
 7     }
 8
 9     public static void insertSort(int[] array) {
10         int j;
11         for(int i = 1; i < array.length; i++) {
12             if(array[i] < array[i - 1]) {
13                 int temp = array[i];
14                 for(j = i - 1; j >= 0 && array[j] > temp; j--) {
15                     array[j + 1] = array[j];
16                 }
17                 array[j + 1] = temp;
18             }
19         }
20     }
21 }

最好情况,比较n-1次,交换0次,时间复杂度为O(n)

最坏情况,比较2+3+4+……+n=(n-1)*(n-2)/2次,交换3+4+……+(n+1)=(n-1)*(n+4)/2次

4、shell排序

 1 public class ShellSort {
 2
 3     public static void main(String[] args) {
 4         int[] array = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
 5         shellSort(array);
 6         System.out.println(Arrays.toString(array));
 7     }
 8
 9     public static void shellSort(int[] array) {
10         int increment = array.length;
11         int j;
12         do {
13             increment = increment/3 +1;
14             for(int i = increment; i < array.length; i++) {
15                 if(array[i] < array[i - increment]) {
16                     int temp = array[i];
17                     for(j = i - increment; j >= 0 && array[j] > temp; j -= increment) {
18                         array[j + increment] = array[j];
19                     }
20                     array[j + increment] = temp;
21                 }
22             }
23         } while(increment > 1);
24     }
25 }

increment如何选取是一个尚未解决的数学难题

5、堆排序

 1 public class HeapSort {
 2
 3     public static void main(String[] args) {
 4         int[] array = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
 5         heapSort(array);
 6         System.out.println(Arrays.toString(array));
 7     }
 8
 9     public static void heapSort(int[] array) {
10         for (int i = array.length / 2; i > 0; i--) {//构建成大顶锥
11             heapAdjust(array, i, array.length);
12         }
13         for (int i = array.length - 1; i > 0; i--) {
14             int temp = array[0];
15             array[0] = array[i];
16             array[i] = temp;
17             heapAdjust(array, 1, i);  //重新调整为大顶堆
18         }
19     }
20
21     public static void heapAdjust(int[] array, int s, int m) {
22         int temp, i, largest; //largest中存关键字较大的记录下标
23         temp = array[s - 1]; //表示第s个节点
24         for (i = 2 * s; i <= m; i *= 2) {
25             if (i < m && array[i - 1] < array[i]) {
26                 largest = i;
27             } else
28                 largest = i - 1;
29             if (temp >= array[largest])
30                 break;
31             array[s - 1] = array[largest];
32             s = largest + 1;
33         }
34         array[s - 1] = temp;
35     }
36 }

堆排序的运行时间主要消耗在初始构建堆和反复筛选堆上,初始构建是从二叉树最下层最右边非终端节点开始。对每个非终端节点来说,最多进行两次比较和互换,时间复杂度为O(n)。

正式排序时,第i次取堆顶,重建堆要用O(nlogi) (完全二叉树某节点到根节点距离为[log2i] +1,并且需要取n-1次堆顶),因此时间复杂度为O(nlogn)。

6、归并排序

递归实现:

 1 public class MeargeSort {
 2
 3     public static void main(String[] args) {
 4         int[] array = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
 5         mergeSort(array, 0, array.length - 1);
 6         System.out.println(Arrays.toString(array));
 7     }
 8
 9     public static void mergeSort(int[] array, int start, int end) {
10         if(start < end) {
11             int mid = (start + end)/2;
12             mergeSort(array, start, mid);
13             mergeSort(array, mid + 1, end);
14             merge(array, start, mid, end);
15         }
16     }
17
18     public static void merge(int[] array, int s, int m, int e) {
19         int i, j, k;
20         int[] temp = new int[array.length];
21         for(i = s, j = m + 1, k = s; i <= m && j <= e; k++) {
22             if(array[i] < array[j]) {
23                 temp[k] = array[i++];
24             } else {
25                 temp[k] = array[j++];
26             }
27         }
28         if(i <= m) {
29             for(int l = 0; l <= m - i; l++) {
30                 temp[k + l] = array[i + l];
31             }
32         }
33         if(j <= e) {
34             for(int l = 0; l <= e - j; l++) {
35                 temp[k + l] = array[j + l];
36             }
37         }
38         for(i = s; i <= e; i++) {
39             array[i] = temp[i];
40         }
41     }
42 }

非递归实现:

 1 public class CycleMergeSort {
 2
 3     public static void main(String[] args) {
 4         int[] array = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
 5         mergeSort(array);
 6         System.out.println(Arrays.toString(array));
 7     }
 8
 9     public static void mergeSort(int[] array) {
10         int width = 1;
11         while(width < array.length) {
12             mergePass(array, width);
13             width *= 2;
14         }
15     }
16
17     public static void mergePass(int[] array, int width) {
18         int start = 0;
19         while(start + 2 * width -1 < array.length) {
20             merge(array, start, start + width -1, start + 2 * width -1);
21             start = start + 2 * width;
22         }
23         if(start + width -1 < array.length) {
24             merge(array, start, start + width -1, array.length - 1);
25         }
26     }
27
28     public static void merge(int[] array, int s, int m, int e) {
29         int i, j, k;
30         int[] temp = new int[array.length];
31         for(i = s, j = m + 1, k = s; i <= m && j <= e; k++) {
32             if(array[i] < array[j]) {
33                 temp[k] = array[i++];
34             } else {
35                 temp[k] = array[j++];
36             }
37         }
38         if(i <= m) {
39             for(int l = 0; l <= m - i; l++) {
40                 temp[k + l] = array[i + l];
41             }
42         }
43         if(j <= e) {
44             for(int l = 0; l <= e - j; l++) {
45                 temp[k + l] = array[j + l];
46             }
47         }
48         for(i = s; i <= e; i++) {
49             array[i] = temp[i];
50         }
51     }
52 }

一趟归并需要将长度为n的序列进行两两归并,时间复杂度为O(n),二叉树深度为[logn]+1,因此时间总复杂度为O(nlogn)

递归法空间复杂度为归并过程中用到的原始数组的副本O(n)及递归栈log2n, 非递归方法的空间复杂度为O(n)

7、快速排序

 1 public class Qsort {
 2
 3     public static void main(String[] args) {
 4         int[] array = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
 5         Qsort(array, 0, array.length -1);
 6         System.out.println(Arrays.toString(array));
 7     }
 8
 9     public static void Qsort(int[] array, int low, int height) {
10         if(low < height) {
11             int povit = partition(array, low, height);
12             Qsort(array, low, povit - 1);
13             Qsort(array, povit + 1, height);
14         }
15     }
16
17     public static int partition(int[] array, int low, int height){
18         int povit = array[low];
19         while(low < height) {
20             while(low < height && array[height] >= povit) {
21                 height--;
22             }
23             swap(array, low, height);
24             while(low < height && array[low] <= povit) {
25                 low++;
26             }
27            swap(array, low, height);
28         }
29         return low;
30     }
31
32     public static void swap(int[] array,int a, int b) {
33         int temp = array[a];
34         array[a] = array[b];
35         array[b] = temp;
36     }
37 }

最好情况时间复杂度O(nlogn),最差为O(n2)

最好情况下空间复杂度为O(logn),最差情况下空间复杂度为O(n),平均复杂度为O(logn)

快排整体性能优越,但排序不稳定,需要大量辅助空间,对少量数据排序无优势



数据基本有序情况下,不考虑四种复杂排序算法



七大排序算法分析及java实现

原文地址:https://www.cnblogs.com/javaXRG/p/11173662.html

时间: 2024-10-11 12:52:29

七大排序算法分析及java实现的相关文章

【转】八大排序算法分析及JAVA实现

 原文地址http://blog.csdn.net/without0815/article/details/7697916 http://www.cnblogs.com/liuling/p/2013-7-24-01.html 排序大的分类可以分为两种:内排序和外排序.在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,则称为外排序.下面讲的排序都是属于内排序. 内排序有可以分为以下几类: (1).插入排序:直接插入排序.二分法插入排序.希尔排序. (2).选择排序:简单选

各种排序算法分析及其Java实现

排序可分为两种:内排序和外排序.在排序过程中,全部记录存放在内存,称为内排序:如果排序过程中需要使用外存,则成为外排序. 内排序有以下几类: 插入类排序:直接插入排序.二分法(折半)插入排序.希尔(缩小增量)排序 选择类排序:简单选择排序.堆排序 交换类排序:冒泡排序.快速排序.三路划分的快速排序 归并类排序:二路归并排序 基数类排序:MSD基数排序.LSD基数排序 各种内部排序算法的比较 直接插入排序.气泡排序和简单选择排序是基本的排序方法.它们平均情况下的时间复杂度都是O(n2),它们的实现

[转]各种排序算法及其java程序实现

原文:http://blog.csdn.net/t12x3456/article/details/7430700 各种排序算法:冒择路(入)兮(稀)快归堆,桶式排序,基数排序 冒泡排序,选择排序,插入排序,稀尔排序,快速排序,归并排序,堆排序,桶式排序,基数排序 一.冒泡排序(BubbleSort)1. 基本思想: 两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止.2. 排序过程: 设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的

7种基本排序算法的Java实现

7种基本排序算法的Java实现 转自我的Github 以下为7种基本排序算法的Java实现,以及复杂度和稳定性的相关信息. 以下为代码片段,完整的代码见Sort.java 插入排序 1 /** 2 * 直接插入排序 3 * 不稳定 4 * 时间复杂度:O(n^2) 5 * 最差时间复杂度:O(n^2) 6 * 空间复杂度:O(1) 7 * 使用场景:大部分元素有序 8 * @param elements 9 * @param comparator 10 * @param <T> 11 */ 1

排序算法分析【五】:归并排序(附Python&amp;C++代码)

归并排序:将两个已经排序的串行合并成一个串行的操作. 算法原理 先看动态图: 算法描述如下: 申请空间,使其大小为两个已经排序串行之和,该空间用来存放合并后的串行: 设定两个指针,最初位置分别为两个已经排序串行的起始位置: 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置: 重复步骤3直到某一指针到达串行尾: 将另一串行剩下的所有元素直接复制到合并串行尾. 算法实现 Python版: #-*- encoding: utf-8 -*- def merge_sort(l

排序算法分析【一】:插入排序(附Python&amp;C++代码)

本文除了代码是自己写的,其余部分都是已存在内容.作者只是整理归纳学习,肯定不是原创,但是不是翻译,更不是转载,所以只能标注为原创,因为代码是原创.向前辈敬礼! 一.基本概念 排序算法(Sorting algorithm):将一串数据依照特定排序方式进行排列的一种算法. 排序算法是基础中的基础,重中之重.是某些算法如搜索算法.合并算法的前置算法.排序不仅仅是对数值排序,也可以是字符串. 排序算法的要求: 1.输出结果为递增(和需要排序的目标相同): 2.输出为输入的重新排列: 相关概念:[摘自百度

朴素贝叶斯算法分析及java 实现

1. 先引入一个简单的例子 出处:http://www.ruanyifeng.com/blog/2013/12/naive_bayes_classifier.html 一.病人分类的例子 让我从一个例子开始讲起,你会看到贝叶斯分类器很好懂,一点都不难. 某个医院早上收了六个门诊病人,如下表. 症状 职业 疾病 打喷嚏 护士 感冒 打喷嚏 农夫 过敏 头痛 建筑工人 脑震荡 头痛 建筑工人 感冒 打喷嚏 教师 感冒 头痛 教师 脑震荡 现在又来了第七个病人,是一个打喷嚏的建筑工人.请问他患上感冒的

常见排序算法总结(java实现)

所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.常见的排序算法有选择排序,插入排序,希尔排序,归并排序和快速排序 由于在排序的过程中不可避免的要涉及到比较和交换,所以将他们抽取为两个单独的函数,如下所示 //为了排序代码的通用性,这里假定待排序的元素实现了Comparable接口 private static boolean less(Comparable v ,Comparable w){ return v.compareTo(w)<0; } priva

排序算法----快速排序java

快速排序是对冒泡排序的一种改进,平均时间复杂度是O(nlogn) import java.util.Arrays; import java.util.Scanner; public class test02{ public static void main(String[] args) { int n = 1; while (n != 0){ Scanner scanner = new Scanner(System.in); n = scanner.nextInt(); int s[] = ne