冒泡排序 (Bubble Sort)
- 基本原理: 从第一个数开始两两比较大小,较大的数下沉。
动画演示
以数组[7, 12, 20, 8, 13, 19, 5, 5]为例
第1趟比较 比较7次
7和12 比较 不交换
12 20 比较 不交换
20 8比较 交换 数组变为[7, 12, 8, 20, 13, 19, 5, 5]
20 13 比较 交换 数组变为[7, 12, 8, 13, 20, 19, 5, 5]
20 19 比较 交换 数组变为[7, 12, 8, 13, 19, 20, 5, 5]
20 5 比较 交换 数组变为[7, 12, 8, 13, 19, 5, 20, 5]
20 5 比较 交换 数组变为[7, 12, 8, 13, 19, 5, 5, 20]
第一趟比较结束后 最后的位置是数组中最大的数
第2趟比较 比较6次
7 12 比较 不交换
12 8 比较 交换 数组变为[7, 8, 12, 13, 19, 5, 5, 20]
12 13 比较 不交换
13 19 比较 不交换
19 5 比较 交换 数组变为 [7, 8, 12, 13, 5, 19, 5, 20]
19 5 比较 交换 数组变为 [7, 8, 12, 13, 5, 5, 19, 20]
第2趟比较结束后 n-2索引的位置是数组中第二大的数
依次类推
下方为动画演示
第一趟演示:
完整版演示:
程序实现(java)
public void bubbleSort(int[] arr){
int tmp;
//n-1趟
for (int i = 0; i < arr.length-1; i++) {
//比较 n-1-i 次
for (int j = 0; j < arr.length-1-i; j++) {
//swap
if (arr[j]>arr[j+1]){
tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] =tmp;
}
}
}
for (int k:arr
) {
System.out.println(k);
}
}
选择排序(SelectSort)
- 原理:
对于长度为n的arr数组,第一次遍历从0~n-1中找出最小的数 和arr[0] 置换,然后从 1~n-1中找出最小的数和arr[1]置换,遍历n-1次。
动画演示
数组:[7, 12, 20, 8, 13, 19, 5]
程序实现(java)
private static void selectSort(int[] arr) {
int minIndex;
int temp;
//遍历 n-1 次
for (int i = 0; i < arr.length; i++) {
minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j;
}
}
// i minIndex swap
if (i != minIndex) {
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
堆排序(HeapSort)
- 原理:堆排序是利用堆这种数据结构所设计的一种排序算法,堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点,是一种选择排序
- 过程 :
1 将无需序列构建成一个堆,最大堆or最小堆;
2 将堆顶元素与末尾元素交换,将最大(小)元素交换到数组末端;
3 重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
堆
- 性质:
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
大顶堆
- 数组调整至最大堆
以数组 [7, 12, 20, 8, 13, 19, 5,10]为例
数组初始状态
动图
程序
void initHeap(int[] arr){
int length = arr.length;
for (int i = length/2 -1; i >=0 ; i-- ){
adjustHeap(arr,i,length);
}
}
void adjustHeap(int[] arr,int i,int len){
int left=2*i+1;
int right=2*i+2;
int max = i;
if (right<len && arr[right]>arr[max]){
max = right;
}
if (left<len && arr[left] > arr[max]){
max = left;
}
if (max == i){
return;
}
swap(arr,i,max);
adjustHeap(arr,max,len);
}
void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
动图演示
程序实现(java)
static void heapSort(int[] arr){
// 将无序数列构造成最大堆
int length = arr.length;
for (int i = length/2 -1; i >=0 ; i-- ){
adjustHeap(arr,i,length);
}
for (int i = arr.length-1; i >0 ; i--) {
//交换
swap(arr,0,i);
//调整堆
adjustHeap(arr,0,i);
}
for (int k:arr
) {
System.out.println(k);
}
}
static void adjustHeap(int[] arr,int i,int len){
int left=2*i+1;
int right=2*i+2;
int max = i;
// 从父节点 子节点中选出最大,如果有子节点大于父节点 交换
if (right<len && arr[right]>arr[max]){
max = right;
}
if (left<len && arr[left] > arr[max]){
max = left;
}
if (max == i){
return;
}
swap(arr,i,max);
adjustHeap(arr,max,len);
}
static void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
排序算法比较
排序算法 | 平均时间复杂度 | 平均空间复杂度 | 是否稳定 |
---|---|---|---|
冒泡排序 | O(n2) | O(1) | T |
选择排序 | O(n2) | O(1) | F |
堆排序 | O(nlogn) | O(nlogn) | F |
题外话
推荐一个可视化算法的网站
https://visualgo.net/