经典排序算法

一.算法的分类

经典排序算法_第1张图片

相关概念:

稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。

不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。

时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。

空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

二.冒泡排序(BubbleSort)

冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。 

核心思想:相邻逆序就交换

1.1 算法描述

  • 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
  • 针对所有的元素重复以上的步骤,除了最后一个;
  • 重复步骤1~3,直到排序完成。

1.2 动图演示

经典排序算法_第2张图片

1.3 代码实现

import java.util.Scanner;

public class BubbleSort {
    public static void main(String[] args) {
        //int a[] = {12,1,3,4,7,2,5};
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一维数组,数组长度为10:");
        int[] a = new int[10];
        for(int i = 0;i < 10;i++){
            a[i] = scanner.nextInt();
        }
        bubbleSort(a);
        System.out.println("冒泡排序后的顺序:");
        for(int i=0;ia[j+1]){
                    int temp = a[j+1];
                    a[j+1] = a[j];
                    a[j] = temp;
                }
            }
        }
    }
}

       N个元素需要排序N-1轮;

  第i轮需要比较N-i次;

  N个元素排序,需要比较n(n-1)/2次;

  冒泡排序的算法复杂度较高,为O(n*n)

三.快速排序(Quick Sort)

改进冒泡排序中一次只能消除一个逆序的缺点,即实现一次交换消除多个逆序

快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

经典排序算法_第3张图片

package com.luo.sort;

public class QuickSort {
    public static void main(String[] args) {
        int arr[] = {3,5,1,4,7,9,8};
        int start = 0;
        int end = arr.length - 1;
       quickSort(arr,start,end);
        for (int i=0;i=right){
            return;
        }

        int key = arr[left] ;

        while (left=key && right>left){
                right--;
            }
            //找到之后,替换掉基准位的值
            if(leftleft){
                left++;
            }
            //找到之后,填补右侧之前替换掉的基准位的值的位置空缺
            if(left

 四.选择排序

 选择排序是对冒泡排序的改进,它的比较次数与冒泡排序相同,但交换次数要小于冒泡排序。当数据量较大时,效率会有很大的提升,但时间复杂度仍为O(n*n)

原理:

       1、从第一个元素开始,分别与后面的元素向比较,找到最小的元素与第一个元素交换位置;

  2、从第二个元素开始,分别与后面的元素相比较,找到剩余元素中最小的元素,与第二个元素交换;

  3、重复上述步骤,直到所有的元素都排成由小到大为止。

待比较数据:7, 6, 9, 8, 5,1

  第一轮:此时指针指向第一个元素7,找出所有数据中最小的元素,即1,交换7和1的位置,排序后的数据为:1,6,9,8,5,7

  第二轮:第一个元素已经为最小的元素,此时指针指向第二个元素6,找到6,9,8,5,7中最小的元素,即5,交换5和6的位置,排序后的结果为:1,5,9,8,6,7

  第三轮:前两个元素为排好序的元素,此时指针指向第三个元素9,找到9,8,6,7中最小的元素,即6,交换6和9的位置,排序后的结果为:1,5,6,8,9,7

  第四轮:前三个元素为排好序的元素,此时指针指向第四个元素8,找到8,9,7中最小的元素,即7,交换8和7的位置,排序后的结果为:1,5,6,7,9,8

  第五轮:前四个元素为排好序的元素,此时指针指向第五个元素9,找到9,8中最小的元素,即8,交换9和8的位置,排序后的结果为:1,5,6,7,8,9

  到此,全部排序完成。

package com.luo.sort;

public class SelectSort {
    public static void main(String[] args) {
        int[] arr =  {6,1,2,7,9,3,4,5,10,8};
        selectSort(arr);
        for (int i=0;iarr[j]){
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
//    private static void selectSort(int[] arr) {
//
//
//        //外层循环记录排序的t趟数,和冒泡排序类似,N个元素进行N-1趟排序
//        for(int i=0;i

      N个元素需要排序N-1轮;

  第i轮需要比较N-i次;

  N个元素排序,需要比较n(n-1)/2次;

  选择排序的算法复杂度仍为O(n*n);

  相比于冒泡排序,选择排序的交换次数大大减少,因此速度要快于冒泡排序

五.插入排序

插入排序是简单排序中最快的排序算法,虽然时间复杂度仍然为O(n*n),但是却比冒泡排序和选择排序快很多。

原理:插入排序算法有种递归的思想在里面,它由N-1趟排序组成。初始时,只考虑数组下标0处的元素,只有一个元素,显然是有序的。

然后

第一趟 对下标 1 处的元素进行排序,保证数组[0,1]上的元素有序;

第二趟 对下标 2 处的元素进行排序,保证数组[0,2]上的元素有序;
.....
.....
第N-1趟对下标 N-1 处的元素进行排序,保证数组[0,N-1]上的元素有序,也就是整个数组有序了。

它的递归思想就体现在:当对位置 i 处的元素进行排序时,[0,i-1]上的元素一定是已经有序的了。

待比较数据:7, 6, 9, 8, 5,1

  第一轮:指针指向第二个元素6,假设6左面的元素为有序的,将6抽离出来,形成7,_,9,8,5,1,从7开始,6和7比较,发现7>6。将7右移,形成_,7,9,8,5,1,6插入到7前面的空位,结果:6,7,9,8,5,1

  第二轮:指针指向第三个元素9,此时其左面的元素6,7为有序的,将9抽离出来,形成6,7,_,8,5,1,从7开始,依次与9比较,发现9左侧的元素都比9小,于是无需移动,把9放到空位中,结果仍为:6,7,9,8,5,1

  第三轮:指针指向第四个元素8,此时其左面的元素6,7,9为有序的,将8抽离出来,形成6,7,9,_,5,1,从9开始,依次与8比较,发现8<9,将9向后移,形成6,7,_,9,5,1,8插入到空位中,结果为:6,7,8,9,5,1

  第四轮:指针指向第五个元素5,此时其左面的元素6,7,8,9为有序的,将5抽离出来,形成6,7,8,9,_,1,从9开始依次与5比较,发现5比其左侧所有元素都小,5左侧元素全部向右移动,形成_,6,7,8,9,1,将5放入空位,结果5,6,7,8,9,1。

  第五轮:同上,1被移到最左面,最后结果:1,5,6,7,8,9。

package com.luo.sort;

public class InsertSort {
    public static void main(String[] args) {
        int[] arr = {6,1,2,7,9,3,4,5,10,8};
        insertSort(arr);
        for(int i=0;i0)&&(arr[j]

 

 

 

你可能感兴趣的:(数据结构与算法)