常见的排序

常见的排序方法有:冒泡排序、快速排序、选择排序、插入排序、希尔排序,甚至还有基数排序、鸡尾酒排序、桶排序、鸽巢排序、归并排序等。

JAVA实现常见的排序

冒泡排序(Bubble Sort):相邻的2个元素相互依次比较,大的往后放,经过一次循环就会拿到最大的,多次循环实现排序

实现原理图

java排序哪种方法更好 java排序方式有几种_java排序哪种方法更好

代码实现:

public static void bubbleSort(int[] arr){
        for (int i =0 ;i < arr.length-1; i++){ //执行arr.length-1次循环
            for (int j =0; j< arr.length-1-i; j++){ //每次循环去比较并替换,每循环一次确定最大的值
                if(arr[j] > arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }

时间复杂度:O(n^2)

 

选择排序(Selection sort):从0索引开始,依次同后面的元素比较,小的往前放,一次循环后拿到最小的,多次循环实现排序

实现原理图:

java排序哪种方法更好 java排序方式有几种_i++_02

代码实现

public static void selectSort(int[] arr){
        for (int i =0 ;i < arr.length-1; i++){ //执行arr.length-1次循环
            for (int j =i+1; j< arr.length; j++){ //0索引同1,2,3,4比较,1索引同2,3,4比较,依次类推
                if(arr[i] > arr[j]){
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }

时间复杂度:O(n^2)

 

快速排序(Quicksort):通过一趟排序将要排序的数据分割成独立的两部分,其中左部分的数据都比右部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,递归进行,以此达到整个数据变成有序序列。

实现原理图:

java排序哪种方法更好 java排序方式有几种_i++_03

实现步骤:

  1. 选择一个支点将数据分成2部分,可以任意选择,一般选择中间那个数据;左部分是9,5,2,右部分是2,7,6
  2. 最左边的start指针,往右移动,每次移动前比较当前位置的元素与支点元素大小,如果大于支点,则这个元素就是要被替换到支点右边,如果不大于则继续右移,直到找到大于支点的元素
  3. 最右边的end指针,往左移动,每次移动前比较当前位置的元素同支点元素的大小,如果小于支点元素,则这个元素就要被替换到支点左边,如果不小于,则继续左移,直到找到大于支点的元素
  4. 左右2个指针找到替换的元素,执行替换,替换完继续移动,直到2个指针重合,第一次循环完成,在递归对左右2分布分别执行此操作 

代码实现:

/**
     * 
     * @param arr
     * @param start 起始指针
     * @param end 结尾指针
     */
    public static void quickSort(int[] arr,int start,int end){
        int i = start;
        int j = end;
        int pivot = arr[(i + j) /2]; //支点是数组中的一个值
        while(i <= j){ //i和j这2个指针只要没重叠(交换左右位置),就执行循环
            while(arr[i] < pivot){ //一直右移找到大于支点值得索引i
                i++;
            }
            while(arr[j] > pivot){//一直坐移找到小于支点值得索引j
                j--;
            }
            if(i<=j){ //找到上面说的2个索引,就替换他们的位置,这里判断i<=j才操作
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] =temp;
                i++; //交换完后继续移动
                j--; //交换完后继续移动,在判断
            }
        }
        //执行到这里,第一次循环完成,可以保证支点索引位置的左边的所有元素比支点索引右面的元素小
        if(start < j){
            quickSort(arr,start,j);
        }
        if(end > i){
            quickSort(arr,i,end);
        }

    }

时间复杂度:O(n*logn)

 

插入排序(InsertSort):将数组的第一个数认为是有序数组,从前往后(从后往前)扫描该有序数组,把数组中其余n-1个数,根据数值的大小,插入到有序数组中,直至数组中的所有数有序排列为止。这样的话,n个元素需要进行n-1趟排序

实现步骤:

  1. 外层循环表示的是排序的趟数,n个数字需要n-1趟,因此,外层循环的次数是n-1次;同时也代表数的位置。
  2. 每次需要排序的第i个元素(i > 0),则表示前面i -1 个元素是有序的(如排i=1的元素的时候,表示i=0这个元素是有序的,i=2元素的时候,i=0和i=1这2个元素有序),需要排序的元素依次和前面的元素比较,通过不断往前排+遇到顺序不对就替换,从而形成排序

代码实现:

public static void insertSort(int[] arr){
        for(int i=1; i<arr.length; i++) { //经历n-1次循环
            for(int j = i; j > 0 ; j--){ //需要排序的元素是第i个元素,前i-1个元素默认是有序的
                if(arr[j] < arr[j-1]){
                    int temp = arr[j];
                    arr[j] =arr[j-1];
                    arr[j-1]=temp;
                }

            }
        }
    }

时间复杂度:O(n^2)