基于比较的排序算法:冒泡、插入、堆、归并、快速(Java实现)

因为这学期上算法课,因为要准备蓝桥杯国赛,所以复习记录一下几个经典的算法 (T_T)。。。

时间复杂度 T(n)算法稳定性
冒泡排序O(n2)稳定
插入排序O(n2)稳定
堆排序O(n)不稳定
归并排序O(nlogn)稳定
快速排序O(nlogn)不稳定

1.冒泡排序

冒泡排序的基本思想:
对于n个元素的数组,算法执行n-1次;
对于第i次,从第一个元素开始,依次与后面元素进行比较,一直比较到n-i次;
如果该元素比后面元素大,则交换元素。

import java.util.Random;

/**
 *  @author: cuttle
 *  @Date: 2020/9/30 16:24
 *  @Description: 对产生的随机数据进行冒泡排序
 */
public class BubbleSort {
    public int[] array;
    public BubbleSort(int n){
        array = new int[n];
        initArray();
    }
    public void initArray(){
        Random random = new Random(97);
        for(int i = 0;i < array.length;i++){
            array[i] = random.nextInt();
        }
    }
    public void bubbleSort(){
        for(int i = 1;i < array.length;i++){
            boolean hasSwap = false;
            for(int j = 0;j < array.length - i;j++){
                if(array[j+1] < array[j]){
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                    hasSwap = true;
                }
            }
            if(!hasSwap){
                break;
            }
        }
    }
    public void printArray(){
        for(int i = 0;i < array.length;i++){
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }
     public static void main(String[]args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用于排序的数据数量n:");
        int  n = sc.nextInt();
        BubbleSort bs = new BubbleSort(n);
        System.out.println("排序前:");
        bs.printArray();
        System.out.println("----------------开始排序----------------");
        long start = System.currentTimeMillis();
        bs.bubbleSort();
        long end = System.currentTimeMillis();
        System.out.println("----------------结束排序----------------");
        System.out.println("冒泡排序所用时间" + (end - start) + "ms");
        System.out.println("排序后:");
        bs.printArray();
    }
}

2.插入排序

插入排序的算法思想:
假设前i-1个元素已经排好,现在考虑第i(2 ≤ i ≤ n)个元素;
首先将第i个元素赋值给X;
X与第i-1、i-2…1个元素比较;
如果大于X,那么右移,将X放入空出的位置。

import java.util.Random;

/**
 *  @author: cuttle
 *  @Date: 2020/9/30 17:24
 *  @Description: 对产生的随机数据进行插入排序
 */
public class InsertionSort {
    public int[] array;
    int x;
    int j;
    public InsertionSort(int n){
        array = new int[n];
        init();
    }
    public void init(){
        Random random = new Random(97);
        for(int i = 0;i < array.length;i++){
            array[i] = random.nextInt();
        }
    }
    public void insertionSort(){
        for(int i = 1;i < array.length;i++){
            x = array[i];
            j = i - 1;
            while(j >= 0 && array[j] > x){
                array[j+1] = array[j];
                j--;
            }
        }
    }
    public void printArray(){
        for(int i = 0;i < array.length;i++){
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }
     public static void main(String[]args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用于排序的数据数量n:");
        int  n = sc.nextInt();
        InsertionSort is = new InsertionSort(n);
        System.out.println("排序前:");
        is.printArray();
        System.out.println("----------------开始排序----------------");
        long start = System.currentTimeMillis();
        is.insertionSort();
        long end = System.currentTimeMillis();
        System.out.println("----------------结束排序----------------");
        System.out.println("插入排序所用时间" + (end - start) + "ms");
        System.out.println("排序后:");
        is.printArray();
    }
}

3.堆排序

堆排序的算法思想:
首先将输入的数据创建为一个堆;
交换堆中的第一个元素和最后一个元素,则新的最后一个元素即是已经排好序的元素;
将堆的大小减1,并对第1个元素执行节点下移操作。
继续该过程,当堆的大小减为1时,就完成了排序。

import java.util.Random;

/**
 *  @author: cuttle
 *  @Date: 2020/9/30 16:24
 *  @Description: 对产生的随机数据进行堆排序
 */
public class HeapSort {
    public int[] array;
    public int n;
    public HeapSort(int n){
        array = new int[n];
        this.n = n;
        initArray();
    }
    public void initArray(){
        Random random = new Random(97);
        for(int i = 0;i < n;i++){
            array[i] = random.nextInt();
        }
    }
    public void makeHeap(){
        for(int i = n / 2 - 1;i >= 0;i--){
            siftDown(n,i);
        }
    }
    public void siftDown(int n,int i){
        boolean done = false;
        while(!done && (i = 2 * i + 1) < n){
            if(i + 1 < n && array[i+1] > array[i])
                i = i + 1;//找到子节点中比较大的一个
            if(array[(i-1)/2] < array[i]){
                int temp = array[i];
                array[i] = array[(i-1)/2];
                array[(i-1)/2] = temp;
            }else{
                done = true;
            }
        }
    }
    public void heapSort(){
        makeHeap();
        for(int i = n - 1;i > 0;i--){
            int temp = array[0];
            array[0] = array[i];
            array[i] = temp;
            siftDown(i,0);
        }
    }
    public void printArray(){
        for(int i = 0;i < array.length;i++){
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }
     public static void main(String[]args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用于排序的数据数量n:");
        int  n = sc.nextInt();
        HeapSort hs = new HeapSort(n);
        System.out.println("排序前:");
        hs.printArray();
        System.out.println("----------------开始排序----------------");
        long start = System.currentTimeMillis();
        hs.heapSort();
        long end = System.currentTimeMillis();
        System.out.println("----------------结束排序----------------");
        System.out.println("堆排序所用时间" + (end - start) + "ms");
        System.out.println("排序后:");
        hs.printArray();
    }
}

4.归并排序

归并排序算法基本思想:
归并排序是一个典型的分治算法:
1.分解:首先将排序数组分解为左右两个等大的不重叠的子数组;
2.解决:递归;
3.合并:将两个已经有序的数组合并为一个有序的数组。

import java.util.Random;

/**
 *  @author: cuttle
 *  @Date: 2020/10/14 16:34
 *  @Description: 对产生的随机数据进行归并排序
 */
public class MergeSort {
    public int[] array;
    public MergeSort(int n){
        array = new int[n];
        initArray();
    }
    public void initArray(){
        Random random = new Random(97);
        for(int i = 0;i < array.length;i++){
            array[i] = random.nextInt();
        }
    }
    public void mergeSort(int low,int high){
        if(low < high){
            int mid = (low + high) / 2;
            mergeSort(low,mid);
            mergeSort(mid+1,high);
            merge(low,mid,high);
        }
    }
    public void merge(int p,int q,int r){
        int i = p;
        int j = q + 1;
        int k = p;
        int[] b = new int[r + 1];
        while (i <= q && j <= r){
            if(array[i] < array[j]){
                b[k++] = array[i++];
            } else {
                b[k++] = array[j++];
            }
        }
        if(i == q+1){
            for(;j <= r;j++){
                b[k++] = array[j];
            }
        }else {
            for(;i <= q;i++){
                b[k++] = array[i];
            }
        }
        for(int m = p;m <= r;m++){
            array[m] = b[m];
//            System.out.print(b[m]+" ");
        }
//        System.out.println();
    }
    public void printArray(){
        for(int i = 0;i < array.length;i++){
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }
     public static void main(String[]args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用于排序的数据数量n:");
        int  n = sc.nextInt();
        MergeSort ms = new MergeSort(n);
        System.out.println("排序前:");
        ms.printArray();
        System.out.println("----------------开始排序----------------");
        long start = System.currentTimeMillis();
        ms.mergeSort(0,n-1);
        long end = System.currentTimeMillis();
        System.out.println("----------------结束排序----------------");
        System.out.println("归并排序所用时间" + (end - start) + "ms");
        System.out.println("排序后:");
        ms.printArray();
    }
}

5.快速排序

快速排序算法基本思想:
使用分治策略把待排序数据序列分为两个子序列:
1.挑出一个元素,成为“枢纽”元素pivot;
2.分区:将所有比枢纽元素小的元素放在枢纽元素前面,所有比枢纽元素大的元素放在枢纽元素后面;
3.将枢纽元素前面和后面的子序列用步骤2递归。

import java.util.Random;

/**
 *  @author: cuttle
 *  @Date: 2020/10/14 16:35
 *  @Description: 对产生的随机数据进行快速排序算法
 */
public class QuickSort {
    public int[] array;
    public QuickSort(int n){
        array = new int[n];
        initArray();
    }
    public void initArray(){
        Random random = new Random(97);
        for(int i = 0;i < array.length;i++){
            array[i] = random.nextInt();
        }
    }
    public void quickSort(int low,int high){
        if(low < high){
            int p = partition(low,high);
            quickSort(low,p - 1);
            quickSort(p + 1,high);
        }
    }
    public int partition(int low,int high){
        int pivot = array[high];
        int i = low - 1;
        for(int j = low;j <= high-1;j++){
            if(array[j] < pivot){
                i = i + 1;
                if(i < j){
                    swap(i,j);
                }
            }
        }
        if(array[high] < array[i + 1]){
            swap(high,(i + 1));
        }
        return i + 1;
    }
    public void swap(int i,int j){
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    public void printArray(){
        for(int i = 0;i < array.length;i++){
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }
    public static void main(String[]args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用于排序的数据数量n:");
        int  n = sc.nextInt();
        QuickSort qs = new QuickSort(n);
        System.out.println("排序前:");
        qs.printArray();
        System.out.println("----------------开始排序----------------");
        long start = System.currentTimeMillis();
        qs.quickSort(0,n - 1);
        long end = System.currentTimeMillis();
        System.out.println("----------------结束排序----------------");
        System.out.println("快速排序所用时间" + (end - start) + "ms");
        System.out.println("排序后:");
        qs.printArray();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值