排序算法之冒泡、插入、快排和选择排序

怎甘沉沦 提交于 2019-12-02 11:14:22
排序算法大全

package cn.baidu;

import java.util.Arrays;

public class SortTest {

    public static void main(String[] args) {
        int[] arr = { 2, 5, 3, 1, 4 };
        System.out.println("排序前:" + Arrays.toString(arr));
        // InsertSort.sort(arr);
        // BubbleSort.sort(arr);
        // SelectionSort.sort(arr);
        // ShellSort.sort(arr);
        // QuickSort.sort(arr);
        // MergeSort.sort(arr);
        // HeapSort.sort(arr);
        System.out.println("排序后:" + Arrays.toString(arr));
    }

    /*
     * 交换数组中的两个元素
     */
    public static void swap(int[] data, int i, int j) {
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
}

 /**
     * 冒泡排序(稳定)
     * @param array
     
     冒泡排序(Bubble Sort)也是一种简单直观的排序算法.它重复地走访过要排序的数列,一次比较两个元素,
     如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.
     这个算法的名字由来是因为越小的元素会经由交换的慢"浮"到数列的顶端.
     
     算法步骤 :
        1: 比较相邻的元素.如果第一个比第二个大,就交换他们两个.
        2: 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.这步做完后,最后的元素会是最大的数.
        3: 针对所有的元素重复以上的步骤,除了最后一个.
        4: 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较.
     
     
     */
    public static void bubbleSort(int[] array){
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = 0; j < (array.length - 1 - i); j++) {
                if(array[j] > array[j+1]){
                    swap(array, j, j+1);
                }
            }
            System.out.println(Arrays.toString(array));
        }
    }

package cn.baidu;

/*
 * 插入排序基本思想
 * 将n个元素的数列分为已有序和无序两个部分,如插入排序过程示例下所示:   
 * {{a1},{a2,a3,a4,…,an}}   
 * {{a1⑴,a2⑴},{a3⑴,a4⑴ …,an⑴}}  
 * {{a1(n-1),a2(n-1) ,…},{an(n-1)}}   
 * 每次处理就是将无序数列的第一个元素与有序数列的元素从后往前逐个进行比较,
 * 找出插入位置,将该元素插入到有序数列的合适位置中。
 
 插入排序是一种罪简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,
 找到相应位置并插入.
 
 算法步骤 :
    1: 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是末排序序列.
    2: 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置.(如果待插入的元素与有序序列中的某个元素相等
    ,则将待插入元素插入到相等元素的后面.
 
 
 */
public class InsertSort {
    public static void sort(int[] data) {
        for (int i = 1; i < data.length; i++) {
            for (int j = i; (j > 0) && (data[j] < data[j - 1]); j--) {
                SortTest.swap(data, j, j - 1);
            }
        }

    }
}

/*
 * 选择排序基本思路:
 * 把第一个元素依次和后面的所有元素进行比较。
 * 第一次结束后,就会有最小值出现在最前面。
 * 依次类推
 选择排序(Selection sort)也是一种简单直观的排序算法
 
 算法步骤 :
    1: 首先在末排序序列中找到最小(最大)元素,存放到排序序列的起始位置.
    2: 再从剩余末排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾
    3: 重复第二步,直到所有元素均排序完毕.
 
 */
public class SelectionSort {
    public static void sort(int[] data) {
        for (int x = 0; x < data.length - 1; x++) {
            for (int y = x + 1; y < data.length; y++) {
                if (data[y] < data[x]) {
                    SortTest.swap(data, x, y);
                }
            }
        }
    }
}
  /**
     * 快速排序(不稳定): 所谓的不稳定是当两个相同的数字在数组中的时候,会出现一种情况,就是把这两个相同的数给交换了位置.
     * @param array
     快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
    快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

    算法步骤:
    1 从数列中挑出一个元素,称为 “基准”(pivot),
    2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
    3 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

    递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
         
     */
    public static void quickSort(int[] array){
        quickSort(array, 0, array.length - 1);
    }

    private static void quickSort(int[] array, int low, int high) {
        int i = low, j = high;
        int pivot = array[(low + high)/2];//中间位置值
        while (i <= j){
            while(array[i] < pivot){
                i++;
            }
            while(array[j] > pivot){
                j--;
            }

            if(i <= j){
                swap(array, i, j);
                i++;
                j--;
            }
        }
        if(i < high){
            quickSort(array, i, high);
        }
        if(j > low){
            quickSort(array, low, j);
        }
    }

    /**
     * 交换数组值
     * @param array
     * @param i
     * @param j
     */
    private static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
}

package com.dn.sort;


public class BinaryInsertSort {
    public static void main(String[] args) {
        int[] a={49,38,65,97,176,213,227,49,78,34,12,164,11,18,1};
        System.out.println("排序之前:");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
        //二分插入排序
        sort(a);
        System.out.println();
        System.out.println("排序之后:");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
    }
//二分法插入
    private static void sort(int[] a) {
        for (int i = 0; i < a.length; i++) {
            int temp = a[i];
            int left = 0;
            int right = i-1;
            int mid = 0;
            //确定要插入的位置
            while(left<=right){
                //先获取中间位置
                mid = (left+right)/2;
                if(temp<a[mid]){
                    //如果值比中间值小,让right左移到中间下标-1
                    right = mid-1;
                }else{
                    //如果值比中间值大,让left右移到中间下标+1
                    left = mid+1;
                }
            }
            for (int j = i-1; j >= left; j--) {
                //以左下标为标准,在左位置前插入该数据,左及左后边全部后移
                a[j+1] = a[j];
            }
            if(left != i){
                //左位置插入该数据
                a[left] = temp;
            }
        }
    }
}

package com.dn.sort;

public class InsertSort {
/**
 * 直接插入排序
 * @param args
 */
        public static void main(String[] args) {
            int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1};
            System.out.println("排序之前:");
            for (int i = 0; i < a.length; i++) {
                System.out.print(a[i]+" ");
            }
            //直接插入排序
            for (int i = 1; i < a.length; i++) {
                //待插入元素
                int temp = a[i];
                int j;
                for (j = i-1; j>=0; j--) {
                    //将大于temp的往后移动一位
                    if(a[j]>temp){
                        a[j+1] = a[j];
                    }else{
                        break;
                    }
                }
                a[j+1] = temp;//插入进来
            }
            System.out.println();
            System.out.println("排序之后:");
            for (int i = 0; i < a.length; i++) {
                System.out.print(a[i]+" ");
            }
        }
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!