各种排序

来源:互联网 发布:手机管理网络的软件 编辑:程序博客网 时间:2024/06/05 16:45

直接插入排序

排序方式

每次将一个待排序的元素与已排序的元素进行逐一比较,直到找到合适的位置按大小插入。

这里写图片描述

package com.zl.test;/** * Created by acer on 2017/6/20. */public class Sort {    /**     * 直接插入排序     * @param arr 要排序的数组     */    public void insertSort(int[] arr) {        int i,j,temp;        for(i = 1;i < arr.length; i ++){            if(arr[i] < arr[i-1]){//注意[0,i-1]都是有序的。                // 如果待插入元素比arr[i-1]还大则无需再与[i-1]前面的元素进行比较了                // 反之则进入if语句                temp = arr[i];                for(j = i-1; j >= 0 && arr[j] > temp; j --){                    arr[j+1] = arr[j];//把比temp大或相等的元素全部往后移动一个位置                }                arr[j+1] = temp;//把待排序的元素temp插入腾出位置的(j+1)            }        }    }}

折半插入排序

排序方式

  1. 直接插入排序,是当要将第i个数插入数组arr时,是先和arr[i-i]比较。而折半插入排序,是在直接插入的基础上改进的,它是和0~i-1的中间点(0+i-1)/2比较,即arr[i]与arr[(0+i-1)/2]比较

  2. 若arr[i]>arr[(0+i-1)/2],则就继续与(0+i-1)/2~i-1的中间点比较,在相应的半个范围里面找插入的位置时,不断的用(1)步骤缩小范围,不停的折半,范围依次缩小为 1/2 1/4 1/8 …….快速的确定出第 i 个元素要插在什么地方;反之亦然

  3. 确定位置之后,将整个序列后移,并将元素插入到相应位置。

    /**     * 折半插入排序     * @param arr 要排序的数组     */    public static void binaryInsertSort(int[] arr){        for(int i = 1; i < arr.length; i ++){            int temp = arr[i];            int left = 0;            int right = i-1;            while(left <= right){//通过拆装查找找到插入位置                int mid = (left+right)/2;                if(temp < arr[mid]){//插入点在[left,mid-1]                    right = mid-1;                }else               //插入点在[mid+1,right]                    left = mid+1;            }//直到找到合适的位置(left或right+1),接下来就将left/right+1后的元素后移            for(int j = i-1;j >= right+1; j --){                arr[j+1] = arr[j];            }            arr[right+1] = temp;        }    }

快速排序

排序方式
任取一个数据(如第一个数据)作为分界值,所有比它小的数据元素一律放到左边,所有比它大的数据元素放到右边

  1. 选出指定的基准(PivotKey)
  2. 将所有小于分界值的数据元素放在左边
  3. 将所有大于分界值的数据元素放到右边

这里写图片描述

    /**     * 快速排序     *初始值 start =0 ; end = arr.length     * @param arr 要排序的数组     */    public static void quickSort(int[] arr,int low ,int high) {        int key = arr[low];        int start = low;  //        int end = high; //        while (end > start) {            while (end > start && arr[end] > key) {//如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较                end--;            }            if (arr[end] <= key) {                int temp = arr[end];                arr[end] = arr[start];                arr[start] = temp;            }            //从前往后比较            while (end > start && arr[start] <= key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置                start++;            if (arr[start] >= key) {                int temp = arr[start];                arr[start] = arr[end];                arr[end] = temp;            }            //此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用        }        //递归        if (start > low) quickSort(arr, low, start - 1);//左边序列。第一个索引位置到关键值索引-1        if (end < high) quickSort(arr, end + 1, high);//右边序列。从关键值索引+1到最后一个    }

希尔排序

排序方式
先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。

    /**     * 希尔排序     *     * @param arr 要排序的数组     */    public static void shellSort(int[] arr) {        int h = 1;//保存可变增量        //按h * 3 + 1得到增量序列的最大值        while (h <= arr.length / 3) {            h = h * 3 + 1;        }        while (h > 0) {            System.out.println("====h的值:" + h + "====");            for (int i = h; i < arr.length; i++) {                int tmp = arr[i];                if (arr[i] < arr[i - h]){                    int j = i - h;                    //整体后移h位                    for (; j >= 0 && arr[j] > tmp; j -= h) {                        arr[j + h] = arr[j];                    }                    arr[j + h] = tmp;                }                System.out.println(Arrays.toString(arr));            }            h = (h - 1) / 3;        }    }
原创粉丝点击