排序算法集合
十大排序算法
快排
递归实现
1 | class Solution { |
非递归实现
1 | class Solution{ |
快排应用
插入排序
冒泡排序
基数排序
归并排序
算法步骤
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
- 重复步骤
3
直到某一指针达到序列尾; - 将另一序列剩下的所有元素直接复制到合并序列尾。
源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Solution {
int[] tmp;
public int[] sortArray(int[] nums) {
tmp = new int[nums.length];
mergeSort(nums, 0, nums.length - 1);
return nums;
}
public void mergeSort(int[] nums, int l, int r) {
if (l >= r) return;
int m = (l + r) >> 1;
mergeSort(nums, l, m);
mergeSort(nums, m + 1, r);
int i = l, j = m + 1;
int cnt = 0;
// 合并两个有序数组
while (i <= m && j <= r) {
if (nums[i] < nums[j]) {
tmp[cnt++] = nums[i++];
}else {
tmp[cnt++] = nums[j++];
}
}
// 左边没用完
while (i <= m) tmp[cnt++] = nums[i++];
// 右边没用完
while (j <= r) tmp[cnt++] = nums[j++];
// 放到原来的数组中
for (int k = 0; k < r - l + 1; ++k) {
nums[k + l] = tmp[k];
}
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/sort-an-array/solution/pai-xu-shu-zu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
桶排序
堆排序
- 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
- 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;
算法步骤
- 创建一个堆 $H[0……n-1]$;
- 把堆首(最大值)和堆尾互换;
- 把堆的尺寸缩小
1
,并调用maxHeapify(0)
,目的是把新的数组顶端数据调整到相应位置; - 重复步骤
2
,直到堆的尺寸为1
。代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41class Solution {
public void heapSort(int[] nums) {
int heapSize = nums.length;
// 建最大堆在这里进行
buildMaxHeap(nums, heapSize);
// 排序在这里进行
for (int i = heapSize - 1; i > 0; i--) {
swap(nums, 0, i);
heapSize--;
maxHeapify(nums, 0, heapSize);
}
}
// 建大根堆
public void buildMaxHeap(int[] nums, int heapSize) {
for (int i = heapSize / 2; i >= 0; i--) {
maxHeapify(nums, i, heapSize);
}
}
public void maxHeapify(int[] nums, int index, int headSize) {
// l代表左子树的元素,r代表右子树的元素,largest是当前的根节点元素的index
int l = index * 2 + 1, r = index * 2 + 2, largest = index;
// 如果左子树的节点大于当前的最大值,最大的是左子树的根节点的index对应的值
if (l < headSize && nums[l] > nums[largest]) largest = l;
// 如果右子树的节点大于当前的最大值,最大的是右子树的根节点的index对应的值
if (r < headSize && nums[r] > nums[largest]) largest = r;
// 如果最大的不是根节点的值,需要交换最大值与根节点的值,从最大值的index继续heapify
if (largest != index) {
swap(nums, index, largest);
maxHeapify(nums, largest, headSize);
}
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
堆排序的应用
找最大的k个数
1 | class Solution { |
插入排序
1 | package runoob; |