Skip to content

Commit

Permalink
0104 supplement
Browse files Browse the repository at this point in the history
  • Loading branch information
yk committed Jan 8, 2024
1 parent ff23b0c commit 743eb36
Showing 1 changed file with 82 additions and 1 deletion.
83 changes: 82 additions & 1 deletion content/posts/2024/01/0104.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: '0104'
date: 2024-01-04T15:37:23+08:00
lastmod:
lastmod: 2024-01-08
tags: []
series: []
categories: []
Expand All @@ -23,6 +23,12 @@ public static void swap(int[] arr, int i, int j) {
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
// 保险还是用这个吧~
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
```

### 冒泡
Expand Down Expand Up @@ -295,6 +301,34 @@ private static int[] partition(int[] arr, int l, int r) {
}
```

## 堆排序

堆就是一组数字从左往右逐个填满二叉树,这就是满二叉树,也就是堆了。特殊的堆是大/小根堆,也叫优先队列。比如 React 的底层就用了小根堆,java 中的 PriorityQueue 默认也是小根堆,可以传入比较器来控制。

### 上浮和下沉

上浮就是当数字一个一个进入堆中,从最后往上走,构建出大/小根堆。

```java

```

下沉一般是在堆顶出堆后(与最后一个交换),

```java

```

## 稳定性

稳定性就是相同的数字在排序后仍然保持着相对的位置。这种特性还是比较重要的,比如对一个年级的学生,先按照成绩排序,再按照班级排序。

冒泡选择和插入只有选择排序是不稳定的,因为在它的过程中,会把 min 或 max 与后面的交换,同理快速排序也不是稳定的,堆排序更不用提了~

快速排序: 时间 O(nlogn), 空间 O(logn),相对而言速度最快
归并排序: 时间 O(nlogn),空间 O(n),具有稳定性
堆排序的:时间 O(nlogn),空间 O(1),空间最少

## 拓展:异或的运用

### 一组数,只有一个数出现了一次,其他都是偶数次,找出这个数
Expand Down Expand Up @@ -349,3 +383,50 @@ public static int[] findTwoOdd(int[] arr) {
return new int[]{a, b};
}
```

## 非比较排序复习

非比较排序往往都是牺牲空间换取时间,所以通常是需要数据结构满足一定的条件下才会去使用的。

### 计数排序

计数排序一般适合于样本空间不大的正整数排序,比如人的年龄,一定大于 0 小于 200。(当然对于负数咱可以通过 + 一个数让所有的数都变成正数后再排序, 排序完成后再减去)

```java
/**
* 计数排序
*
* @param arr
* @param k
*/
public static void countSort(int[] arr, int k) {
int[] count = new int[k + 1];
for (int i = 0; i < arr.length; i++) {
count[arr[i]] += 1;
}
int[] bucket = new int[arr.length];
// 构建计数尺子的前缀和,统计频率,基数排序也会用到这种。
// 现在: count[i] 的含义为 arr 中 <= i 的数字有多少个
for (int i = 1; i < count.length; i++) {
count[i] += count[i - 1];
}
// 从右往左遍历原数组,根据count统计的频率进行排序
// 从右往左是为了保证稳定性
for (int i = arr.length - 1; i >= 0; --i) {
bucket[count[arr[i]] - 1] = arr[i];
count[arr[i]]--;
}

for (int i = 0; i < bucket.length; i++) {
arr[i] = bucket[i];
}
}
```

### 基数排序

基数排序比基数排序的使用范围更加广一点,因为是根据每个进位来产生桶,最多也就 0-9 十个桶。

```java

```

0 comments on commit 743eb36

Please sign in to comment.