前言

跟着左神冲冲冲

排序

选择排序

何为选择排序,我们把第一个数拿到,和他后面的所有数相比,取最小的值,然后交换。在拿第二个数,和他后面的所有的数相比,在交换。这个就是选择排序。

所以,比较的角标为

0~n-1

1~n-1

2~n-1

n-2~n-1

核心代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void selectSort(int[] arr) {
//数组为null和长度小于2的直接返回
if (arr == null || arr.length < 2) {
return;
}
int n = arr.length;
int minIndex;
for (int i = 0; i < n; i++) {
minIndex = i;
for (int j = i + 1; j < n; j++) {
//如果最小角标大于当前角标那么替换
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
//交换
swap(arr, i, minIndex);
}
}

冒泡排序

何为冒泡排序,

第一位和第二位比较,那个大就在第二位,

第二位和第三位比较,哪个大就在第三位,

第三位和第四位比较,哪个大就在第四位

。。。

直到比较最后一位,在从第一位到第n-1位比较,具体角标

0~n-1

0~n-2

0~n-3

0~1

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void bubblingSort(int[] arr) {
//数组为null和长度小于2的直接返回
if (arr == null || arr.length < 2) {
return;
}
for (int i = arr.length - 1; i >= 0; i--) {
for (int j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
}
}
}
}

插入排序

何为插入排序,这个需要举例子

1
2
3
4
5
6
7
//元数据 5, 1, 5, 3, 123, 124, 51, 7, 2, 3, 1, 1, 1, 1, 1, 2
/**
* 第一次 1, 5, 5, 3, 123, 124, 51, 7, 2, 3, 1, 1, 1, 1, 1, 2
* 第二次 1, 5, 5, 3, 123, 124, 51, 7, 2, 3, 1, 1, 1, 1, 1, 2
* 第三次 1, 3, 5, 5, 123, 124, 51, 7, 2, 3, 1, 1, 1, 1, 1, 2
* 第四次 1, 3, 5, 5, 123, 124, 51, 7, 2, 3, 1, 1, 1, 1, 1, 2
*/

我们已经看到了,每次+1的格式去比较数字,如果后面的大于前面的,就换位置,换成角标就是

0~1

0~2

0~3

0~n

注意,1是不用比较的,后面的数不大于前面的数也是不用继续比较的。原理呢,我们可以这样思考:

我从第一个数开始排序,他一直是从小往大的数字顺序排,那我再比较下一位的时候,只需要往前面慢慢比较即可,知道不大于前面的数,就像插入进去。

实现1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void insertSort1(int[] arr) {
//数组为null和长度小于2的直接返回
if (arr == null || arr.length < 2) {
return;
}
int minIndex;
//这里直接取1,因为角标是0不需要比较,我们只需要比较end以内的角标数就行
for (int end = 1; end < arr.length; end++) {
minIndex = end;
//minIndex最小是1,我们是以第二个数字为准
while (minIndex - 1>= 0 && arr[minIndex-1] > arr[minIndex]) {
swap(arr, minIndex, minIndex - 1);
minIndex--;
}
}
}

实现2

1
2
3
4
5
6
7
8
9
10
11
12
public static void insertSort2(int[] arr) {
//数组为null和长度小于2的直接返回
if (arr == null || arr.length < 2) {
return;
}
//这里直接取1,因为角标是0不需要比较,我们只需要比较end以内的角标数就行
for (int end = 1; end < arr.length; end++) {
for (int i = end; i - 1 >= 0 && arr[i - 1] > arr[i]; i--) {
swap(arr, i, i - 1);
}
}
}

其他

打印整数二进制

首先我们明确一个点,整形是4个字节,一个字节是8位,所以整形是32位。也就是说他的最大值是2的32次方?nonono,他是-2^31~2^31-1,为什么呢,因为他第一位是代表正负,0是正,1是负。为什么2^31-1呢,因为有0这个数字。

正题

知道一个正整数如何把他的二进制打出来呢?举个例子:5的二进制是

1
00000000000000000000000000000101

如果我们想5的第一个位 单独& 1 那么1 &1 就是1 ,第二位&1 就是0,第三位还是1

我们怎么准确的&呢?只需要把需要&1的位置变成1其他位置都是0即可,就像

00000000000000000000000000000001,00000000000000000000000000000010

具体举例,按5举例

源二进制 & 十进制结果
00000000000000000000000000000101 00000000000000000000000000000001 1
00000000000000000000000000000101 00000000000000000000000000000010 0
00000000000000000000000000000101 00000000000000000000000000000100 4
00000000000000000000000000000101 00000000000000000000000000001000 0

聪明的朋友已经知道了,这不是就是1往左移位数吗,对应java就是1<<x,x是要移的位数,所以最终是

1
2
3
4
5
6
7
8
9
/**
* 打印一个整形的二进制
* @param num
*/
public static void printBinary(int num) {
for (int i = 31; i >= 0; i--) {
System.out.print((num & (1 << i)) == 0 ? "0" : "1");
}
}