1、时间复杂度以及简单排序

119 阅读2分钟

1、认识时间复杂度

说到时间复杂度之前,首先我们先了解什么是常数操作?

  • 常数操作是一种与数据量无关的一种操作,每次都是固定时间内完成的操作。例如数组当中的取值操作,还有加减乘除以及位运算这一系列的操作都是常数操作。 时间复杂度总体来说就是常数操作数量的表达式:
  • 时间复杂度为一个算法流程中,常数操作数量的一个指标。常用O(读作big O)来表示。具体来说,先要对一个算法流程非常熟悉,然后去写出这个算法流程中,发生了多少常数操作,进而总结出常数操作数量的表达式。(与数据量无关的操作)

2、选择排序

选择排序的具体思想 先记录表第一个下标,比较该下标的值与后面的值的大小,如果哪个小,就和第一个下标交换。然后下标加1.这样就每次都能保证当前下标是最小的数。代码如下:0到n-1的位置上找到一个最小的数,放到0位置上,然后1到n-1的位置上找到最小的数,放到1位置上。然后2到n-1,后面依次循环。

public class Code01_SelectionSort {
    public static void selectionSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        //最后一个元素不用比较,所以只到倒数第二个下标,也可以理解为因为上一个下标的范围直到长度减一就行
        for (int i = 0; i < arr.length - 1; i++) {
            //先记下当前位置的下标,假如这个下标的值是最小值
            int minIndex = i;
            //与下一个下标开始的数做比较,找出了最小值的下标,所以这里也可以是小于等于arr.length-1
            for (int j = i + 1; j < arr.length; j++) {
            // j和minIndex下标做比较,找出最小值的坐标
                minIndex = arr[j] < arr[minIndex] ? j : minIndex;
            }
            //最小值的下标和之前记录i的坐标交换
            swap(arr, i, minIndex);
        }
    }

    public static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static void main(String[] args) {
        int[] arr = {5, 4, 3, 7, 9, 1};
        selectionSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

3、冒泡排序

每次最大的值往右移动,最大的每次都能排到后面。

public class Code2_BubbleSort {
    public static void bubbleSort(int[] arr) {
        //外层控制整个循环
        for (int e = arr.length - 1; e > 0; e--) {
            //每次将最大的那个排到最后
            for (int i = 0; i < e; i++) {
                //如果前一个大于了后面一个 我们就交换
                if (arr[i] > arr[i + 1]) {
                    swap(arr, i, i + 1);
                }
            }
        }
    }

    //可以用异或运算(相同为0 不同为1就是异或运算)(无进位相加)
    public static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static void main(String[] args) {
        int[] arr={5,4,3,7,9,1};
        bubbleSort(arr);
        System.out.println(Arrays.toString(arr));

    }

}

4、插入排序

public class Code03_InsertionSort {
    public static void insertionSort(int[] arr) {

        if (arr == null || arr.length < 2) {
            return;
        }
        //外层控制
        //从第二个开始,所以就是i开始
        for (int i = 1; i < arr.length; i++) {
            //新插入的是j+1,与前一个进行比较,也就是j。如果j大于就交换。
            //其实新插入时,前面已经都排好序了
            for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
                swap(arr, j, j + 1);
            }
        }

    }

    public static void swap(int[] arr, int i, int j) {
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
 }

5、异或运算

异或运算 就是 相同为0,不同为1.也可以理解为不进位的二进制运算。 异或运算还有三个性质:

  1. 0^N=N N^N=0。
  2. 满足交换律和结合律。
  3. 异或运算不考虑顺序问题,同一批数,异或的结果是一样。
  4. 但是异或运算要保持的是,两个数不能指向的是同一内存空间,可以值相同。