数据库--排序(直接插入排序 希尔排序 直接选择排序 双向选择排序 堆排序 冒泡排序)

 排序算法

1.直接插入排序

        每次从无序区间的第一和元素开始,依次与有序区间内的元素从后往前比较 。如果当前有序区间内的元素大于无序区间,则将有序区间该下标元素后移 插入

 public static void insertSort(int[] array) {
        //有序区间:[0,i)
        //无序区间:[i,array.length)
        for (int i = 1; i < array.length; i++) {//外层循环找的是无序区间
            int k = array[i];//k为无序区间第一个数
            int j;//有序区间最后一个数
            for (j = i - 1; j >= 0 && array[j] > k; j--) {//遍历的是有序区间
                array[j + 1] = array[j];
            }//从有序区间的最后一个元素开始比较
            // 如果大于无序区间元素 则将有序区间的元素后移 最后插入元素
            array[j + 1] = k;//因为最后循环退出的时候j--了 而真正要将无序区间插入的下标在后一个
        }
    }//直接插入排序

2.希尔排序

        希尔排序时直接插入排序的升级版,将数组元素分成(size/2)/((size/3)+1)各组 进行直接插入排序 然后重复上述分组过程 分组 插排

public static void shellSort(int[] array) {
        int gap = array.length;
        while (true) {
            gap = (gap / 3) + 1;//希尔排序的分组数 也可以为gap/2
            insertSortWithGapa(array, gap);
            if (gap == 1) {
                break;
            }
        }
    }

    private static void insertSortWithGapa(int[] array, int gap) {
        for (int i = gap; i < array.length; i++) {//从第二组请开始依次遍历整个数组
            int k = array[i];
            int j;
            for (j = i - gap; j >= 0 && array[j] > k; j -= gap) {//将每一组的元素都与前面几组相对应组的元素比较
                array[j + gap] = array[j];
            }
            array[j+gap] = k;//当循环退出的时候 j的下标减了依次gap
        }
    }//希尔排序

3.直接选择排序

       整个数组看成一个无序区间  每次从无序区间中选择最小(最大) 放入无序区间最前(最后)位置 ,一直到所有元素都排完

  1. 放在无序区间前面时 无序区间下标为[i,array,length)
  2. 放在无序区间后面时 无序区间下标为[0,array.length-i)
   public static void selectSortSmall(int[] array) {
        //无序下标:[i,array.length)
        for (int i = 0; i < array.length - 1; i++) {//外层循环 需要循环array.length-1次才可以有序
            int j;
            int minIndex = i;//设置每次的起始位置为无序序列的第一个位置
            for (j = minIndex; j < array.length; j++) {    //在无序区间查找最小元素
                if (array[j] < array[minIndex])
                    minIndex = j;
            }
            swap(array, minIndex, i);
        }
    }//直接选择排序
    //选择无序区间最小的元素放到无序区间第一个位置


    public static void selectSortBig(int[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            // 无序区间: [0, array.length - i]
            int max = 0;
            for (int j = 1; j < array.length - i; j++) {  //无序区间
                if (array[j] > array[max]) {
                    max = j;
                }
            }
            int t = array[max];
            array[max] = array[array.length - i - 1];
            array[array.length - i - 1] = t;
        }
    }//直接选择排序
    // 选择无序区间最大的元素放到无序区间最后一个位置
    private static void swap(int[] array, int i, int j) {
        int t = array[i];
        array[i] = array[j];
        array[j] = t;
    }

4.双向选择排序

      直接从无序区间每次选出最大和最小元素 分别放在 无序区间最后和最前位置

      特殊情况:当数组中最大元素在第一个位置时 经过与min 交换 当前最大元素下标发生变更 需特殊处理

public static void selectSortOP(int[] array) {
        int begin = 0;
        int end = array.length - 1;
        // [begin,end] 表示整个无序区间
        // 当无序区间内只有一个数时停止排序
        while (begin <= end) {
            int minIndex = begin;
            int maxIndex = begin;//无序区间的最大值和最小值 均设置为第一个元素
            for (int i = begin + 1; i <= maxIndex; i++) {
                if (array[i] < array[minIndex])
                    minIndex = i;
                if (array[i] > array[maxIndex])
                    maxIndex = i;
            }
            swap(array, minIndex, begin);
            if (maxIndex == begin) {
                maxIndex = minIndex;
            }
            swap(array, maxIndex, end);
            begin++;
            end--;
        }
    }//双排

 5.堆排序

  1. 首先对数组进行建堆 建大堆 排升序 建小堆 排降序(我是用大堆 排升序)

  2. 每次让当前树顶元素与最后一个元素进行交换(每交换一次 当前树内元素减1)

  3. 对新的树顶进行向下调整

  public static void heapSort(int [] array){
        createHeap(array);//建大堆
        for(int i=0;i<array.length;i++) {
            swap(array, 0, array.length-1-i);
            //每次让最大的元素与当前树的最后一个节点交换
            //在对新的树顶做向下调整 找大的结点
            shiftDownBig(array, array.length-i-1, 0);//当前无序期间的结点个数
        }
    }//堆排序

    private static void shiftDownBig(int[] array, int size, int index) {
        int left = 2 * index + 1;
        while (left < size)
        {
            int max = left;
            int right = left+1;
            if (right < size)
            {
                if (array[right] > array[left])
                {
                    max = right;
                }
            }
            if (array[index] < array[max])
            {
                swap(array,index,max);
                index = max;
                left = 2 * index + 1;
            }
            else
                break;
        }
    }//对指定下标元素做向下调整

    private static void createHeap(int[] array) {
        for(int j=(array.length-2)/2;j>=0;j--){
                shiftDownBig(array,array.length,j);
        }
    }//建大堆 从最后一个叶子结点的双亲结点开始 依次对其做向下调整

  6.冒泡排序

      在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后,持续这个过程,直到数组整体有序

public static void bubbleSort(int []array){
        for(int i=0;i<array.length;i++){
            for(int j=0;j<array.length-1-i;j++){
                if(array[j]>array[j+1])
                    swap(array,j,j+1);//交换
            }
        }
    }//冒泡排序

7.完整代码 

import java.sql.SQLOutput;
import java.util.Arrays;
import java.util.Random;

public class Sort {
    public static void insertSort(int[] array) {
        //有序区间:[0,i)
        //无序区间:[i,array.length)
        for (int i = 1; i < array.length; i++) {//外层循环找的是无序区间
            int k = array[i];//k为无序区间第一个数
            int j;//有序区间最后一个数
            for (j = i - 1; j >= 0 && array[j] > k; j--) {//遍历的是有序区间
                array[j + 1] = array[j];
            }//从有序区间的最后一个元素开始比较
            // 如果大于无序区间元素 则将有序区间的元素后移 最后插入元素
            array[j + 1] = k;
        }
    }//直接插入排序

    public static void shellSort(int[] array) {
        int gap = array.length;
        while (true) {
            gap = (gap / 3) + 1;//希尔排序的分组数 也可以为gap/2
            insertSortWithGapa(array, gap);
            if (gap == 1) {
                break;
            }
        }
    }

    private static void insertSortWithGapa(int[] array, int gap) {
        for (int i = gap; i < array.length; i++) {//从第二组请开始依次遍历整个数组
            int k = array[i];
            int j;
            for (j = i - gap; j >= 0 && array[j] > k; j -= gap) {//将每一组的元素都与前面几组相对应组的元素比较
                array[j + gap] = array[j];
            }
            array[j+gap] = k;//当循环退出的时候 j的下标减了依次gap
        }
    }//希尔排序

    private static void swap(int[] array, int i, int j) {
        int t = array[i];
        array[i] = array[j];
        array[j] = t;
    }

    public static void selectSortSmall(int[] array) {
        //无序下标:[i,array.length)
        for (int i = 0; i < array.length - 1; i++) {//外层循环 需要循环array.length-1次才可以有序
            int j;
            int minIndex = i;//设置每次的起始位置为无序序列的第一个位置
            for (j = minIndex; j < array.length; j++) {    //在无序区间查找最小元素
                if (array[j] < array[minIndex])
                    minIndex = j;
            }
            swap(array, minIndex, i);
        }
    }//直接选择排序
    //选择无序区间最小的元素放到无序区间第一个位置


    public static void selectSortBig(int[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            // 无序区间: [0, array.length - i]
            int max = 0;
            for (int j = 1; j < array.length - i; j++) {  //无序区间
                if (array[j] > array[max]) {
                    max = j;
                }
            }
            int t = array[max];
            array[max] = array[array.length - i - 1];
            array[array.length - i - 1] = t;
        }
    }//直接选择排序
    // 选择无序区间最大的元素放到无序区间最后一个位置

    public static void selectSortOP(int[] array) {
        int begin = 0;
        int end = array.length - 1;
        // [begin,end] 表示整个无序区间
        // 当无序区间内只有一个数时停止排序
        while (begin <= end) {
            int minIndex = begin;
            int maxIndex = begin;//无序区间的最大值和最小值 均设置为第一个元素
            for (int i = begin + 1; i <= maxIndex; i++) {
                if (array[i] < array[minIndex])
                    minIndex = i;
                if (array[i] > array[maxIndex])
                    maxIndex = i;
            }
            swap(array, minIndex, begin);
            if (maxIndex == begin) {
                maxIndex = minIndex;
            }
            swap(array, maxIndex, end);
            begin++;
            end--;
        }
    }//双排

    public static void heapSort(int [] array){
        createHeap(array);//建大堆
        for(int i=0;i<array.length;i++) {
            swap(array, 0, array.length-1-i);
            //每次让最大的元素与当前树的最后一个节点交换
            //在对新的树顶做向下调整 找大的结点
            shiftDownBig(array, array.length-i-1, 0);//当前无序期间的结点个数
        }
    }//堆排序

    private static void shiftDownBig(int[] array, int size, int index) {
        int left = 2 * index + 1;
        while (left < size)
        {
            int max = left;
            int right = left+1;
            if (right < size)
            {
                if (array[right] > array[left])
                {
                    max = right;
                }
            }
            if (array[index] < array[max])
            {
                swap(array,index,max);
                index = max;
                left = 2 * index + 1;
            }
            else
                break;
        }
    }//对指定下标元素做向下调整

    private static void createHeap(int[] array) {
        for(int j=(array.length-2)/2;j>=0;j--){
                shiftDownBig(array,array.length,j);
        }
    }//建大堆 从最后一个叶子结点的双亲结点开始 依次对其做向下调整
    public static void bubbleSort(int []array){
        for(int i=0;i<array.length;i++){
            for(int j=0;j<array.length-1-i;j++){
                if(array[j]>array[j+1])
                    swap(array,j,j+1);
            }
        }
    }//冒泡排序
public static void testSpeed() {
    Random random = new Random(20190924);
    int[] a = new int[10 * 10000];
    for (int i = 0; i < 10 * 10000; i++) {
        a[i] = random.nextInt(10 * 10000);
    }
    long begin = System.nanoTime();
    heapSort(a);
    long end = System.nanoTime();
    double ms =(end - begin) * 1.0 / 1000 / 1000;
    System.out.printf("一共耗时:%5f毫秒%n", ms);
}

    public static void main(String[] args) {
        int []a={9,5,2,7,3,6,4,8,4,3,9};
        insertSort(a);
        System.out.println(Arrays.toString(a));
        System.out.println("b*========================");

        int []b=a.clone();
        bubbleSort(b);
        System.out.println(Arrays.toString(b));
        System.out.println("c*========================");

        int []c=a.clone();
        shellSort(c);
        System.out.println(Arrays.toString(c));
        System.out.println("d*========================");

        int []d=a.clone();
        heapSort(d);
        System.out.println(Arrays.toString(d));
        System.out.println("e*========================");

        int []e=a.clone();
        selectSortBig(e);
        System.out.println(Arrays.toString(e));
        System.out.println("f*========================");

        int []f=a.clone();
        selectSortSmall(f);
        System.out.println(Arrays.toString(f));
        System.out.println("g*========================");

        int []g=a.clone();
        selectSortOP(g);
        System.out.println(Arrays.toString(g));
    }
}

发布了40 篇原创文章 · 获赞 4 · 访问量 871

猜你喜欢

转载自blog.csdn.net/weixin_44919969/article/details/101391488
今日推荐