认识时间复杂度为O(N ^ 2)的排序

时间复杂度

 一个操作如果和样本的数量没有关系,每次都是固定时间内完成的操作叫做常数操作。  时间复杂度为一个算法流程中,常数操作数量的一个指标。在表达式。

1. 插入排序

 在小量数据中很占优势。插入排序从当前位置和左边的书比较,除非比到头了(到达0位置上的数)或者左边的数比当前数小,停止比较。

在这里插入图片描述

在这里插入图片描述
4和4左边9比较,4比9小,交换位置。
在这里插入图片描述
5和左边9比较,5比9小,交换位置 , 5比4大,比较停止,继续下一步。
在这里插入图片描述
7和左边9比较,7比9小,交换位置 , 7比5大,比较停止,继续下一步

在这里插入图片描述
1和左边9比较,1比9小,交换位置 ,再向前一个比,1比7小,交换位置 ,再向前一个比,1比5小,交换位置 ,再向前一个比, 1比4小,交互位置,继续向前发现到头了,不比了。

在这里插入图片描述
4和左边9比较,4比9小,交换位置 ,再向前一个比,4比7小,交换位置 ,再向前一个比,4比5小,交换位置 ,再向前一个比,4和4相等,不比了。
在这里插入图片描述

3和左边9比较,3比9小,交换位置 ,再向前一个比,3比7小,交换位置 ,再向前一个比,3比5小,交换位置 ,再向前一个比, 3比4小,交互位置,
再向前一个比, 3比4小,继续向前个比发现到3比4小,不比了。在这里插入图片描述
排序完毕。

  public static void insertSort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = i ; j > 0; j--) {
                if (arr [j] > arr[j - 1]) {
                    break;
                }
                arr[j] = arr[j] ^ arr[j - 1];
                arr[j - 1] = arr[j] ^ arr[j - 1];
                arr[j] = arr[j] ^ arr[j - 1];
            }
        }
    }

2. 选择排序

从当前位置向后找,找到最小值,交换我现在的所在位置。
在这里插入图片描述
从当前位置向后找,找到最小值和当前位置交换。

1        4     5       7     9       4     3

从第二个位置向后找,找到最小值和第二个位置交换。

1     3      5     7    9     4    4
从第3个位置向后找,找到最小值和第三个位置交换。

在这里插入图片描述
从第4个位置向后找,找到最小值和第四个位置交换。

在这里插入图片描述

从第5个位置向后找,找到最小值和第5个位置交换。

1   3   4    4    5   9   7

从第6个位置向后找,找到最小值和第6个位置交换。
在这里插入图片描述
排序完成。

  public static void chooseSort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            int min = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }
            if (arr[min] < arr[i]) {
                arr[i] ^= arr[min];
                arr[min] ^= arr[i];
                arr[i] ^= arr[min];
            }
        }
    }

3. 冒泡排序

冒泡排序是和他下一个位置比较,如果右面比左面大,交换位置。冒泡排序闭着眼睛都能写出来,就直接贴代码了,不贴图了。

  public static void bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = i; j < arr.length; i++) {
                if (arr[j] < arr[i]) {
                    arr[j] = arr[i] ^ arr[j];
                    arr[i] = arr[i] ^ arr[j];
                    arr[j] = arr[i] ^ arr[j];
                }
            }
        }
    }

4. 二分法使用场景

  1. 在一个有序数组中,找到某个数是否存在。
  2. 在一个有序数组中,找到>= 某个数最左侧的位置。
  3. 局部最小值问题。

5. 异或运算性质与扩展

定义:
两个集合A, B 相交, 什么是 Exclusive-or:找到 exclusive => 对于 A 来说 exclusive 就是我有你没有的, A - (A U B), 在 PS4, 但是不在 xbox 的游戏对于 B 来说 exclusive 就是我有你没有的, B - (A U B), 在 xbox, 但是不在 PS4 的游戏2. 然后 or 开始运作了, 也就是上面的情况 1 或者 情况 2 都可以.
在这里插入图片描述

  1. 从计算上看 异或,可以把他当成不进位的相加
01
10
11
  1. 0 ^ N = N N ^ N = 0
  2. 异或运算满足交换律和结合律
  3. 不同额外变量交互两个数。
  4. 一个数组中有一种数出现了奇数次,其他数出现了偶数次,怎么找到这个数。
  static int findOddNum(int[] arr) {
        int temp = 0;
        for (int a : arr) {
            temp ^= a;
        }
        return temp;
    }
  1. 一个数组中有2种数出现了奇数次,其他数出现了偶数次,怎么找到这2个数。
 static int[] findTwoOddNum(int[] arr) {
        int temp = 0;
        //两个出现偶数次的数异或值 a ^ b
        for (int a : arr) {
            temp ^= a;
        }
        //现在找到这两个数,由于这两个数不一样,肯定某一个或多位的数1个是0另一个是1
        //那么就找到从右数第一位为1的结果。
        int firstLocationOne = (~temp + 1) & temp;
        int firstOdd = 0;
        
        //把所有的与右位该值不为0的数做异或,就可以得到该位置为1的数,即b
        for (int a : arr) {
            if ((a & firstLocationOne) != 0) {
                firstOdd ^= a;
            }
        }

        //将b与 a ^b 异或的值做异或,就可以得到a了
        return new int[] {firstOdd, firstOdd ^ temp};
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值