(第20讲)各种排序总结

来源:互联网 发布:数控车床编程指令大全 编辑:程序博客网 时间:2024/05/23 19:12
/**
这些代码我都试过,都是正确的
 */
package com.tankxiancheng;

import java.text.ParseException;

public class  Two {
    
    public static void main(String[] args) throws ParseException {
       Two t = new Two();
       int[] arr = {21,231,2,65,4,6,8,7,0,89,-12};
      // t.bubbleSort(arr);冒泡1
    //t.bubbleSort2(arr); System.out.println(java.util.Arrays.toString(arr));
       //t.selectSort(arr);选择
        //t.insertSort(arr);插入
        t.quickSort(arr, 0, arr.length-1);System.out.println(java.util.Arrays.toString(arr));
        int i = t.binarySearch(0, arr.length - 1, 1232, arr);
        if(i==-1) {
            System.out.println("没有找到");
        } else{
            System.out.println("找到了,下标是:"+i);
        }

    }
    //冒泡法,时间复杂度是O(n的2次方),stable sort、In-place sort
    public void bubbleSort(int[] a){
        int temp =0;
        for(int i =0;i<a.length-1;i++){
            for(int j=0;j<a.length-i-1;j++){
                if(a[j]>a[j+1]){
                    temp = a[j];
                    a[j] =a[j+1];
                    a[j+1] = temp;
                }
            }
        }
        System.out.println(java.util.Arrays.toString(a));
    }
    //改进的冒泡法,时间复杂度是O(n),stable sort、In-place sort
    public void bubbleSort2(int[] a){
        boolean b = true;
        int temp = 0;
        for(int i=0;i<a.length-1;i++){
            if(b==false)
                return;
            b = false;
            for(int j=a.length-1;j>i;j--){
                if(a[j]<a[j-1]){
                    temp = a[j];
                    a[j] =a[j-1];
                    a[j-1] = temp;
                    b = true;
                }
            }
        }
    }
    //选择排序:O(n^2) unstable sort、In-place sort
    //快速排序(不使用随机化)是否一定比插入排序快?
//答:不一定,当输入数组已经排好序时,插入排序需要O(n)时间,而快速排序需要O(n^2)时间。
    public void selectSort(int[] a){
        int temp =0;
        for(int i =0; i<a.length-1;i++){
            int minIndex = i;
            for(int j= i+1;j<a.length;j++){
                if(a[minIndex]>a[j]){
                    minIndex = j;
                }
            }
            temp = a[minIndex];
            a[minIndex] = a[i];
            a[i] = temp ;
        }
        System.out.println(java.util.Arrays.toString(a));
    }
    //插入式排序特点:stable sort、In-place sort
    //最优复杂度:当输入数组就是排好序的时候,复杂度为O(n),而快速排序在这种情况下会产生O(n^2)的复杂度。
    //最差复杂度:当输入数组为倒序时,复杂度为O(n^2)
    //插入排序比较适合用于“少量元素的数组”。
    public void insertSort(int[] a){
        for(int i =1;i<a.length;i++){
            int insert = a[i];//指定当前值为要插入的值
            int index = i-1;//记录要插入位置的前一位
            //若前一位有值,且前一位>要插入的值,则前一位右移
            while(index>=0 && a[index]>insert){
                a[index + 1] = a[index];
                index --;
            }
            a[index+1] = insert;//插入
        }
        System.out.println(java.util.Arrays.toString(a));
    }
    //快速排序:unstable sort、In-place sort。
    //最坏运行时间:当输入数组已排序时,时间为O(n^2),最佳运行时间:O(nlgn)
//当然可以通过随机化来改进(shuffle array 或者 randomized select pivot),使得期望运行时间为O(nlgn)。
    //当输入数组的所有元素都一样时,不管是快速排序还是随机化快速排序的复杂度都为O(n^2),
    /*快速排序思想:经过很多趟排序,每一趟的算法是:step1:设置2个变量i,j,排序开始的时候,蛇者I=1,J=N;
     * step2:以第一个数组元素作为关键数据,赋值给X,即X=A[1];step3:从J开始向前搜索,即从后往前找比X小的数,找到交换
     * step4:从I开始往后找,找到第一个大于A[1]的值,交换;step6:重复step3和step4,直到I=J*/
    public void quickSort(int[] a,int left,int right){
        recursive_quickSort(a,left,right);
    }
    //递归快速
    public static void recursive_quickSort(int[] a,int left,int right){
        if (left<right){
            int mid = partiton(a,left,right);
            recursive_quickSort(a,left,mid-1);
            recursive_quickSort(a,mid+1,right);
        }
    }
    //分区
    public static int partiton(int[] a, int left, int right){
         int mid = a[left];//数组的第一个作为中轴
          //枢轴选定后永远不变,最终在中间,前面小后面大
          while (left < right) {
               while (left < right && a[right] >= mid)
                   right--;//从后往前找比mid小的值
               a[left] = a[right];   //比中轴小的记录移到低端
                while (left < right && a[left] <= mid)
                   left++;//从前往后找比mid大的值
               a[right]=a[left];  //比中轴大的记录移到高端
          }//完成一趟
          a[left] = mid; //当left == right,完成一趟快速排序,此时left位相当于空,等待mid补上
          return left;
    }
    //二分查找前提是:数组必须是排好序的,从小到大的
    public int binarySearch(int left, int right, int val, int arr[]) {
        int midIndex = (left / 2) + (right / 2);
        if (val < arr[left] || val > arr[right] || left > right) {
            return -1;
        }
        if (val < arr[midIndex]) {
            return binarySearch(left, midIndex - 1, val, arr);
        } else if (val > arr[midIndex]) {
            return binarySearch(midIndex + 1, right, val, arr);
        } else {
            return midIndex;
        }
    }
        
}
0 0
原创粉丝点击