Java数据结构学习Day2_Java基础排序算法

1.冒泡排序

冒泡排序就是用双重循环,从数组的头部开始遍历,如果当前数比后一个数大,则调换两者的位置,时间复杂度为O(n^2),冒泡排序很好理解,就是相邻两个数字交换位置即可

package Ivan.sort;

public class BubbleSort {
    public static void main(String[] args) {
        int arr[] = {3, 4, 5, 12, -1, -34};
        int temp = 0;
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                if (arr[i] < arr[j]) {
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

2.选择排序

第一次从arr[0] - arr[n-1]中选取最小值与arr[0]交换,第二次从arr[1]-arr[n-1]中再选最小值和arr[1]交换,以此类推,时间复杂度也是o(n^2),选择排序也比较简单,多看两遍代码就能理解,每次选择剩余数组中最小的数和剩余数组中的第一个数交换位置

package Ivan.sort;

public class SelectSort {
    public static void main(String[] args) {
        int arr[] = {1, -1, 3, -4, -5, 5};
        for (int i = 0; i < arr.length; i++) {
            int minIndex = i;
            int min = arr[i];
            for (int j = i + 1; j < arr.length; j++) {
                if (min > arr[j]) {
                    min = arr[j];
                    minIndex = j;
                }
            }
            if (minIndex != i) {
                arr[minIndex] = arr[i];
                arr[i] = min;
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

3.插入排序

把n个待排序的元素看成一个有序表和一个无序表,无序表中有n-1个元素,有序表中只有一个元素,每次排序从无序表中取出一个元素插入到有序表中,最后返回有序表,最坏的时间复杂度也是o(n^2)

package Ivan.sort;

public class insertSort {
    public static void main(String[] args) {
        int arr[] = {1, -1, 3, -4, -5, 5};
        for (int i = 1; i < arr.length; i++) {
            int insertValue = arr[i];
            int index = i - 1;
            while (index >= 0 && insertValue < arr[index]) {
                arr[index + 1] = arr[index];
                index--;
            }
            arr[index + 1] = insertValue;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }

    }
}

4.希尔排序

希尔排序也是一种插入排序,是由简单排序改进之后的一个更高效的版本,把数组进行一定增量的分组,对每组使用直接插入排序算法排序,希尔排序比较难理解的就是步长,可以理解成把第i个元素和i+步长的元素比较大小,交换位置或是移动位置

package Ivan.sort;

public class ShellSort {
    public static void main(String[] args) {
        int arr[] = {1, -1, 3, -4, -5, 5, 34, 67, -4, -4, 15, 6, -523};
        Shell2(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

    //交换式
    public static void Shell(int arr[]) {
        int temp = 0;
        for (int i = arr.length / 2; i > 0; i /= 2) {
            for (int j = i; j < arr.length; j++) {
                for (int k = j - i; k >= 0; k -= i) {
                    if (arr[k] > arr[k + i]) {
                        temp = arr[k];
                        arr[k] = arr[k + i];
                        arr[k + i] = temp;
                    }
                }
            }
        }
    }

    //移动式
    public static void Shell2(int arr[]) {
        for (int i = arr.length / 2; i > 0; i /= 2) {      //i为步长
            for (int j = i; j < arr.length; j++) {
                int k = j;
                int temp = arr[j];
                if (arr[j] < arr[j - i]) {
                    while (k - i >= 0 && temp < arr[k - i]) {
                        arr[k] = arr[k - i];
                        k -= i;
                    }
                    arr[k] = temp;
                }
            }
        }
    }
}

5.快速排序

快排是对冒泡排序的一种改进,基本思想是:经过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据要小,再按此方法对这两部分数据进行快排,递归的思路,快排比较难理解的就是找一个基准数,把左右两边的数都拍好以后,再对左右两边的分别进行快排,要理解递归的思路

package Ivan.sort;

public class quickSort {
    public static void main(String[] args) {
        int arr[] = {1, -1, 3, -4, -5, 5, 34, 67, -4, -4, 15, 6};
        quickSort(arr, 0, arr.length - 1);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

    public static void quickSort(int[] arr, int left, int right) {
        int l = left;
        int r = right;
        int temp = 0;
        int p = arr[(left+right)/2];
        while (l<r){
            //找到左边比p大的值
            while (arr[l]<p){
                l++;
            }
            //找到右边比p小的值
            while (arr[r] > p){
                r--;
            }
            if (l>=r) break;
            //找到了就交换位置
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;

            //交换完后发现arr[l] == p,前移
            if (arr[l] == p){
                r -= 1;
            }
            if (arr[r] == p){
                l += 1;
            }
        }
        //递归左边和右边
        //如果l==r,必须l++,r--,否则栈溢出
        if (l==r){
            l++;
            r--;
        }
        if (left<r) quickSort(arr, left, r);

        if (right>l) quickSort(arr, l, right);
    }
}
posted @ 2020-06-10 23:24  Ivanpp  阅读(101)  评论(0编辑  收藏  举报