四种常用排序算法

一、冒泡排序

1.概述

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

2.算法步骤

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

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

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

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

3.动图演示

4.代码

import java.util.Arrays;

public class BubbleSort{
    public static void main(String[] args) {
        int[] arr={1,9,8,0,5,6,3,7,4,2};
        bubbleSort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void bubbleSort(int[] array) {
        if (array.length == 0){
            System.out.println("数组元素为空");
        }
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length - 1 - i; j++)
                if (array[j + 1] < array[j]) {
                    int temp = array[j + 1];
                    array[j + 1] = array[j];
                    array[j] = temp;
                }
        }
    }
    /* public static int[] bubbleSort(int[] array) {
        if (array.length == 0)
            return array;
        for (int i = 0; i < array.length; i++)
            for (int j = 0; j < array.length - 1 - i; j++)
                if (array[j + 1] < array[j]) {
                    int temp = array[j + 1];
                    array[j + 1] = array[j];
                    array[j] = temp;
                }
        return array;
    } */
}

二、选择排序

1.概述

选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。

2.算法步骤

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

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

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

3.动图演示

4.代码

import java.util.Arrays;

public class SelectionSort{
    public static void main(String[] args) {
        int[] arr={1,9,8,0,5,6,3,7,4,2};
        selectionSort(arr);
        System.out.println(Arrays.toString(arr));
    }
    /*public static int[] selectionSort(int[] array) {
        if (array.length == 0) {
            return array;
        }
        for (int i = array.length-1; i>=0; i--) {
            int maxIndex = i;
            for (int j = i; j >=0; j--) {
                if (array[j] > array[maxIndex]) //找到最大的数
                    maxIndex = j; //将最大数的索引保存
            }
            int temp = array[maxIndex];
            array[maxIndex] = array[i];
            array[i] = temp;
        }
        return array;
    }*/
    public static int[] selectionSort(int[] array) {
        if (array.length == 0)
            return array;
        for (int i = 0; i < array.length; i++) {
            int minIndex = i;
            for (int j = i; j < array.length; j++) {
                if (array[j] < array[minIndex]) //找到最小的数
                    minIndex = j; //将最小数的索引保存
            }
            int temp = array[minIndex];
            array[minIndex] = array[i];
            array[i] = temp;
        }
        return array;
    }
}

三、插入排序

1.概述

插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

2.算法步骤

将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

3.动图演示

4.代码

import java.util.Arrays;

public class InsertionSort {
    public static void main(String[] args) {
        int[] arr={1,9,8,0,5,6,3,7,4,2};
        insertionSort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void insertionSort(int[] array){
        // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
        for (int i=1;i<array.length;i++){
            int temp=array[i];
            // 从已经排序的序列最右边的开始比较,找到比其小的数
            int j=i;
            while (j>0&&temp<array[j-1]){
                array[j]=array[j-1];
                j--;
            }
            // 存在比其小的数,插入
            if(j!=i){
                array[j]=temp;
            }
        }
    }
}

四、快速排序

1.概述

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

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

快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。

2.算法步骤

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

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

(3)递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

3.动图演示

4.代码

import java.util.Arrays;
public class QuickSort {
    public static void main(String[] args) {
        int[] arr={1,9,8,0,5,6,3,7,4,2};
        quicksort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    public static void quicksort(int[] array,int left,int right){
        int a=left;//左下标
        int b=right;//右下标
        int pivot=array[(a+b)/2];//中间值
        int temp=0;
        //while 循环的目的是让比 pivot 值小放到左边
        //比 pivot 值大放到右边
        while (a<b){
            //在 pivot 的左边一直找,找到大于等于 pivot 值,才退出
            while (array[a]<pivot){
                a++;
            }
            //在 pivot 的右边一直找,找到小于等于 pivot 值,才退出
            while (array[b]>pivot){
                b--;
            }
            //如果 left >= right 说明 pivot 的左右两的值, 已经按照左边全部是
            //小于等于 pivot 值, 右边全部是大于等于 pivot 值
            if(a>=b){
                break;
            }
            temp=array[a];
            array[a]=array[b];
            array[b]=temp;
            //arr[left] == pivot 值 相等 b--, 前移
            if(array[a]==pivot){
                b--;
            }
            //arr[right] == pivot 值 相等 a++, 后移
            if(array[b]==pivot){
                a++;
            }
            //如果 left == right, 必须 l++, r--, 否则为出现栈溢出
            if (a==b){
                b--;
                a++;
            }
            //向左递归
            if (left<a){
                quicksort(array,left,a);
            }
            //向右递归
            if (right>b){
                quicksort(array,b,right);
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值