数据结构基本八大排序算法

来源:互联网 发布:李荣浩 杨丞琳 知乎 编辑:程序博客网 时间:2024/06/01 09:45

1.排序算法简介

  由于待排序的记录数量不同,使得排序过程中涉及的存储器不同,可以将排序方法分为两大类:内部排序外部排序。 
  内部排序:待排序记录存放在计算机的随机存储器(内存)中进行的排序过程。内部排序的方法很多,但就其全面性能而言,很难提出一种被认为最好的方法。每一种方法都有自己的优缺点,适合在不同的环境下使用(比如记录的初始排列状态等)。按照排序过程中依据的不同原则对内部排序大概可以分为以下几类:插入排序,交换排序,选择排序,归并排序和基数排序。 
  外部排序:待排序的记录数量很大,内存一次不能容纳全部记录,在排序过程中需要对外存进行访问的排序过程。(内存和外存同时使用) 
  各种排序算法之间的关系罗列: 
  排序算法关系图

2.各种排序算法介绍与实例

2.1直接插入排序

  算法概念:每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表任然有序。 
  算法思想:假设待排序的记录存放在数组R[1..n]中。初始时,R[1]自成1个有序区,无序区为R[2..n]。从i=2起直至i=n为止,依次将R[i]插入当前的有序区R[1..i-1]中,生成含n个记录的有序区。 
  算法示例

//(直接)插入排序,时间复杂度O(n^2),稳定public class InsertSort {    public static void main(String[] args) {        int[] nums = {5,3,2,7,1,4,6};        startSort(nums);        for (int i = 0; i < nums.length - 1; i++) {            System.out.println(nums[i]);        }    }    public static void startSort(int[] nums) {        for (int i = 0; i < nums.length - 1; i++) {            int j = i + 1;            //temp中存放需要插入的元素            int temp = nums[j];            //temp为待插入的元素,和已经有序列表的最后一个数(最大数)进行比较            //若max>temp,max向后移动,temp再和前面的次最大数比较...            //若max<temp,temp直接插入在最后即可            while(i >= 0 && nums[i] > temp) {                nums[j] = nums[i];                i --;                j --;            }            nums[j] = temp;        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

  算法总结:时间复杂度O(n^2),是稳定的排序方式。

2.2希尔排序(缩小增量排序)

  算法概念:也是一种插入排序的算法,但在时间效率上有较大的改进。 
  算法思想: 
  (a)先将整个待排序记录分割成若干个子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。 
  (b)先取一个小于n(n为数组长度)的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2(其中d2小于d1)重复上述的分组和排序,直至所取的增量dt=1(dt<dt-1<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。 
  算法示例

//希尔排序,时间复杂度O(nlogn),不稳定public class ShellSort {    public static void main(String[] args) {        int[] nums = {5,3,2,7,1,4,6};        startSort(nums);        for (int i = 0; i < nums.length - 1; i++) {            System.out.println(nums[i]);        }    }    public static void startSort(int[] nums) {        // 分成2组        int len = nums.length / 2;        while (len >= 1) {            for (int i = 0; i < len; i++) {                // 使用直接插入排序对分组进行排序                for (int j = i; j < nums.length - len; j += len) {                    int k = j + len;                    int temp = nums[k];                    while (j >= 0 && nums[j] > temp) {                        nums[k] = nums[j];                        j -= len;                        k -= len;                    }                    nums[k] = temp;                }            }            len /= 2;        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

  算法总结:时间复杂度O(nlogn),不稳定。

2.3简单选择排序

  算法思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数中再找出最小的数与第二个位置的数交换,如此循环到倒数第二个数,将该数与最后一个数比较,较小的一个放在前一个位置。 
  算法示例

//选择排序,时间复杂度O(n^2),不稳定public class SelectSort {    public static void main(String[] args) {        int[] nums = { 5, 3, 2, 7, 1, 4, 6 };        startSort(nums);        for (int i = 0; i < nums.length - 1; i++) {            System.out.println(nums[i]);        }    }    public static void startSort(int[] nums) {        // 标志位        int position = 0;        for (int i = 0; i < nums.length; i++) {            int j = i + 1;            position = i;            int temp = nums[i];            // 找出后面数中的最小者            for (; j < nums.length; j++) {                if (nums[j] < temp) {                    temp = nums[j];                    position = j;                }            }            nums[position] = nums[i];            nums[i] = temp;        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

  算法总结:时间复杂度O(n^2),不稳定。

2.4堆排序

  算法思想:堆排序是一种用完全二叉树解决问题的高效算法,合法的最大堆就是每一个节点值都要大于或等于它的孩子节点,在数组中可表示为:(i从0开始)arrays[i]>=arrays[2*i+1] && arrays[i]>=arrays[2*i+2],最小堆的概念和最大堆相反,此处采用最大堆。 
  堆排序树的构造过程找最大值过程由下图,数组arrays[0….n]为:17,8,45,84,2,94,刚找到最大值后把最大值即94放在数组的最后面arrays[n],然后进入递归把arrays[0…n-1]再进入下面图这个过程,只是把排好序的最大值不放入到这个过程中,就这样把值一个个的冒出来,找到最大值后把这个最大值放到数组的最后面,进入下一个递归。 
  注意:每次都要扫描整个数组,最先发现不符合最大堆的先调整。 
  堆排序示意图1 
  堆排序示意图2 
  算法示例

//堆排序,时间复杂度O(nlogn),不稳定public class HeapSort {    public static void main(String[] args) {        int[] nums = {5,3,2,7,1,4,6};        int e = nums.length - 1;        nums = startSort(nums,e);        for (int i = 0; i < nums.length - 1; i++) {            System.out.println(nums[i]);        }    }    // 堆排序    public static int[] startSort(int[] nums, int e) {        // 堆中的元素多于1个        if (e > 0) {            initHeap(nums, e);// 初始化堆            // 在一轮的堆排序中,找到了最大值,将最大值与最后一个元素交换,重新开始下一轮            nums[0] = nums[e] + nums[0];            nums[e] = nums[0] - nums[e];            nums[0] = nums[0] - nums[e];            // 递归开始下一轮            startSort(nums, e - 1);        } else {            // 堆中不多于1个元素,不需要进行堆排序            return nums;        }        return nums;    }    // 初始化堆    public static void initHeap(int[] nums, int e) {        int m = (e + 1) / 2; // 父节点的个数        for (int i = 0; i < m; i++) {            boolean flag = buildHeap(nums, e, i);            // 如果父节点和孩子节点之间有交换,需要重新扫描整个树中的父节点            if (flag) {                i = -1;            }        }    }    // 建立堆    public static boolean buildHeap(int[] nums, int e, int i) {        int l_child = 2 * i + 1;// 左孩子        int r_child = 2 * i + 2;// 右孩子        // 没有右孩子的时候只需要比较父节点和左孩子节点的大小        if (r_child > e) {            // 父节点比左孩子节点小,需要交换            if (nums[i] < nums[l_child]) {                // 不使用中间变量交换父节点和左孩子节点的值                nums[i] = nums[i] + nums[l_child];                nums[l_child] = nums[i] - nums[l_child];                nums[i] = nums[i] - nums[l_child];                return true;            } else {                return false;            }        }        // 同时拥有左右两个孩子节点的情况,在三者中找出最大值进行交换        if (nums[i] < nums[l_child]) {            // 父节点比左孩子节点小            if (nums[l_child] > nums[r_child]) {                // 左孩子节点是三者中最大的,和父节点交换                nums[i] = nums[i] + nums[l_child];                nums[l_child] = nums[i] - nums[l_child];                nums[i] = nums[i] - nums[l_child];                return true;            } else {                // 右孩子节点是三者中最大的,和父节点交换                nums[i] = nums[i] + nums[r_child];                nums[r_child] = nums[i] - nums[r_child];                nums[i] = nums[i] - nums[r_child];                return true;            }        } else if (nums[i] < nums[r_child]) {            // 父节点比右孩子节点小            // 右孩子节点是三者中最大的,和父节点交换            nums[i] = nums[i] + nums[r_child];            nums[r_child] = nums[i] - nums[r_child];            nums[i] = nums[i] - nums[r_child];            return true;        }        // 父节点最大,不需要交换        return false;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

  算法总结:时间复杂度O(nlogn),不稳定。

2.5冒泡排序

  算法思想:在要排序的一组数中,将第一个记录的关键字与第二个记录的关键字进行比较,让大的往下沉,小的往上冒,然后再比较第二个和第三个,以此类推。比较完一趟,最大的那个已经放到了最后的位置,这样可以对剩下的n-1个再循环比较。 
  冒泡排序示意图 
  算法示例

//冒泡排序,时间复杂度O(n^2),稳定public class BubbleSort {    public static void main(String[] args) {        int[] nums = {5,3,2,7,1,4,6};        startSort(nums);        for (int i = 0; i < nums.length - 1; i++) {            System.out.println(nums[i]);        }    }    public static void startSort(int[] nums) {        for (int i = 0; i < nums.length - 1; i++) {            for (int j = 0; j < nums.length - 1 - i; j++) {                if (nums[j] > nums[j + 1]) {                    int temp = nums[j];                    nums[j] = nums[j + 1];                    nums[j + 1] = temp;                }            }        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

  算法总结:算法复杂度为O(n^2),稳定的。

2.6快速排序

  算法思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,这里选择第一个元素为基准。一个指向基准元素且整个过程指针不变,一个指向最后一个元素,两者比较,前面的元素大于后面的元素则交换,非基准元素的指针向中心移动一位,继续上述步骤,通过一趟扫描,将待排序列分成两个部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素的位置是排好序后的正确位置,然后再用同样的方法递归地排序两个部分。 
  快速排序是对冒泡排序的一种改进。 
  快速排序示意图 
  算法示例

//快速排序,时间复杂度O(nlogn),不稳定public class QuickSort {    public static void main(String[] args) {        int[] nums = {5,3,2,7,1,4,6};        int low = 0;        int high = nums.length - 1;        nums = startSort(nums,low,high);        for (int i = 0; i < nums.length - 1; i++) {            System.out.println(nums[i]);        }    }     public static int[] startSort(int[] nums,int low,int high) {          //递归的终止条件是low >= high          if(low < high) {           int middle = getMiddle(nums,low,high);           //对基准元素前面部分递归排序           startSort(nums,low,middle-1);           //对基准元素后面部分递归排序           startSort(nums,middle+1,high);          }          return nums;         }         public static int getMiddle(int[] nums, int low,int high) {          //选择基准元素          int temp = nums[low];          //两个指针都向中心处移动,直至相等          while (low < high) {           //右指针的元素总是比基准元素大时           while (low < high && nums[high] >= temp) {            high --;           }           //比基准元素小的移动到左侧           nums[low] = nums[high];           //左指针的元素总是比基准元素小时           while (low <high && nums[low] <= temp) {            low ++;           }           //比基准元素大的移动到右侧           nums[high] = nums[low];          }          nums[low] = temp;          return low;         }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

  算法总结:时间复杂度O(nlogn),不稳定。

2.7归并排序

  算法思想:将两个(或者两个以上)的有序表合并成一个新的有序表,即把待排序序列分成若干个子序列,每个子序列都是有序的,然后再把有序子序列合并为整体有序序列。 
  算法在排序的过程中会将整个序列分成两个数为一单元的组合,然后设定两个指针,最初位置分别为两个已经排序序列(一开始两个单独的数即为两个已经排序的序列)的起始位置,然后比较两个指针所指向的元素,选择相对小的元素放入到临时空间,并移动指针到下一位置,直到某一指针移动到序列尾,将另一序列剩下的所有元素直接复制到合并序列的尾部。 
  归并排序示意图 
  算法示例

//归并排序,时间复杂度O(nlogn),稳定public class MergeSort {    public static void main(String[] args) {        int[] nums = {5,3,2,7,1,4,6};        int low = 0;        int high = nums.length - 1;        startSort(nums,low,high);        for (int i = 0; i < nums.length - 1; i++) {            System.out.println(nums[i]);        }    }    // 归并排序    public static int[] startSort(int[] nums, int low, int high) {        // 找出中间的索引        int mid = (low + high) / 2;        if (low < high) {            // 对左边数组进行递归            startSort(nums, low, mid);            // 对右边数组进行递归            startSort(nums, mid + 1, high);            // 左右归并            merge(nums, low, mid, high);        }        return nums;    }    // 将左右两个有序的子序列进行合并    public static void merge(int[] nums, int low, int mid, int high) {        int[] temp = new int[high - low + 1];        int i = low;// 左指针        int j = mid + 1;// 右指针        int k = 0;        // 把较小的数先移动到新数组中        while (i <= mid && j <= high) {            if (nums[i] < nums[j]) {                temp[k++] = nums[i++];            } else {                temp[k++] = nums[j++];            }        }        // 把左边剩余的数移入数组        while (i <= mid) {            temp[k++] = nums[i++];        }        // 把右边剩余的数移入数组        while (j <= high) {            temp[k++] = nums[j++];        }        // 把新数组中的数覆盖nums数组        for (int k2 = 0; k2 < temp.length; k2++) {            nums[k2 + low] = temp[k2];        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

  算法总结:算法复杂度O(nlogn),稳定。

2.8基数排序

  算法思想:将所有待比较值(正整数)统一为同样的数位长度,数位较短的数前面补0,然后从最低位开始,进行依次排序。这样从最低位一直到最高位排序完成以后,数列就变成了一个有序的序列。 
  在众多的排序方法中,基数排序比较特殊,它是一种不需要进行关键字之间比较的排序方法,利用多关键字的划分,逐渐实现有序。 
  比如:278,109,63,930,589,184,505,269,8,83进行排序的过程如下: 
  (a)第一次分组,每一个元素每一位上的数值都是0~9,所以划分为10组,按照每个元素个位上的数值进行分组: 
              0组:930 
              1组: 
              2组: 
              3组:63,83 
              4组:184 
              5组:505 
              6组: 
              7组: 
              8组:278,8 
              9组:109,589,269 
第一次排序后的结果:930,63,83,184,505,278,8,109,589,269 
  (b)第二次分组,将第一次分组后的结果按照十位上的数进行分组: 
              0组:505,8,109 
              1组: 
              2组: 
              3组:930 
              4组: 
              5组: 
              6组:63,269 
              7组:278 
              8组:83,184,589 
              9组: 
第二次排序后的结果:505,8,109,930,63,269,278,83,184,589 
  (c)第三次分组,将第二次分组后的结果按照百位上的数进行分组: 
              0组:8,63,83 
              1组:109,184 
              2组:278,269 
              3组: 
              4组: 
              5组:505,589 
              6组: 
              7组: 
              8组: 
              9组:930 
第三次排序后的结果:8,63,83,109,184,278,269,505,589,930 
  (d)最高只有百位,没有千位,排序结束,输出结果。 
  算法示例

import java.util.ArrayList;import java.util.List;//基数排序,时间复杂度O(nlogrm),稳定public class RadixSort {    public static void main(String[] args) {        int[] nums = {5,3,2,7,1,4,6};        nums = startSort(nums);        for (int i = 0; i < nums.length - 1; i++) {            System.out.println(nums[i]);        }    }    // 基数排序    public static int[] startSort(int[] nums) {        int max = nums[0];        // 选出数列中的最大值        for (int i = 1; i < nums.length; i++) {            if (nums[i] > max) {                max = nums[i];            }        }        // 计算总共需要比较多少次        // 注意此处小于10的正整数除以10结果为0        int time = 0;        while (max > 0) {            max /= 10;            time++;        }        // 设定10个list保存数据        List<ArrayList<Integer>> queue = new ArrayList<ArrayList<Integer>>();        for (int j = 0; j < 10; j++) {            ArrayList<Integer> dataQueue = new ArrayList<Integer>();            queue.add(dataQueue);        }        // 开始排序        for (int i = 0; i < time; i++) {            for (int j = 0; j < nums.length; j++) {                // 取到当前这个数的对应位置上的一位数                int x = nums[j] % (int) Math.pow(10, i + 1)                        / (int) Math.pow(10, i);                ArrayList<Integer> returnQueue = queue.get(x);                returnQueue.add(nums[j]);                queue.set(x, returnQueue);            }            int count = 0;            for (int k = 0; k < 10; k++) {                while (queue.get(k).size() > 0) {                    ArrayList<Integer> tempQueue = queue.get(k);                    nums[count] = tempQueue.get(0);                    tempQueue.remove(0);                    count++;                }            }        }        return nums;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

  算法总结:时间复杂度O(nlogrm),稳定。

3.各种排序算法的比较

排序算法平均时间复杂度最差时间复杂度稳定性空间复杂度备注插入O(n^2)O(n^2)稳定O(1)基本有序希尔O(nlogn)O(ns)不稳定O(1)s是所选分组选择O(n^2)O(n^2)不稳定O(1)n小的时候堆O(nlogn)O(nlogn)不稳定O(1)n大的时候冒泡O(n^2)O(n^2)稳定O(1)n小的时候快速O(nlogn)O(n^2)不稳定O(nlogn)n大的时候归并O(nlogn)O(nlogn)稳定O(1)n大的时候基数O(logRB)O(logRB)稳定O(n)B是对数(0-9),R是基数(个十百)

  总结:没有哪一种排序算法是绝对最优的,要看具体的应用场景。


转载自:http://blog.csdn.net/u012050416/article/details/50681591

0 0
原创粉丝点击