堆排序
1、原理:
将所给的数据按照从小到大的顺序排序,堆排序是借助二叉树的结构,将每一个父节点和他的左右孩子的值进行比较,将其中最大的值放到父节点的位置;这样排完一遍就会将最大值上浮到根节点的位置,然后将根节点与最后一个位置的元素交换,最终完成排序,可借助图来理解:
堆排序分为两种:大根堆和小根堆(上述将最大值上浮的是大根堆,若将最小值上浮的话就是小根堆啦,方法一样)
2、步骤:
(1)从第一个非叶子节点开始,循环到根节点,把每一个父节点与其左右孩子的最大值交换到父结点处;
(2)把根节点的值和最后一个位置的元素交换值;
(3)重新遍历,进行元素交换,使每一个节点都满足父节点的值大于孩子节点的值;
3、代码实现:
import java.util.Arrays;
import java.util.Random;
/*
* 堆排序
*/
public class HeapSort {
public static void main(String[] args) {
int[] arr = new int[10];
Random rd = new Random();
for (int i = 0; i < arr.length; i++) {
arr[i] = rd.nextInt(100);
}
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
/*
* 实现堆排序
*/
private static void heapSort(int[] arr) {
int n = arr.length-1;
// 从第一个非叶子节点开始,把大值往父节点调整
for(int i=(n-1)/2; i>=0; --i){
adjust(arr, i, arr.length);
}
for(int i=n; i>=0; --i){
//0 <=> i 它们的值进行交换
int tmp = arr[0];
arr[0] = arr[i];
arr[i] = tmp;
//再继续进行堆的调整 adjust
adjust(arr,0,i);
}
}
/*
* 堆的调整函数,把每一个节点,和其左右孩子节点的最大值放到当前节点处
*/
private static void adjust(int[] arr, int i, int length) {
int val = arr[i];//当前父节点的值
for(int j = 2*i+1;j<length;j=2*j+1){
if(j+1 < length && arr[j+1]>arr[j]){//右孩子大于左孩子
j++; //将j指向当前比较大的右孩子
}
if(arr[j] > val){//孩子节点比父节点大时
arr[i] = arr[j];//将孩子节点放到父节点位置
i = j;
}else{
break;
}
}
arr[i] = val;//将最开始的val值放到现在孩子节点的位置
}
}
常见算法小结
1、朴素算法
2、KMP算法
3、哈希表
4、形状树
5、冒泡排序算法
6、选择排序算法
7、插入排序算法
8、快速排序算法
9、归并排序算法
应用
1、朴素算法用于常用的字符串的查找,解决:在字符串S中找到字符串T并返回T在S中第一个字母的下标的问题;
2、KMP算法也是用于字符串的查找,但是他是朴素算法的优化,具有更高的效率;
3、哈希表
优点:增删查:时间复杂度为O(1)
缺点:
1、占用内存比较大
2、元素没有任何顺序
用于海量数据中的查找,效率较高。
4、形状树
时间复杂度为O(m),其中m是字符串的长度常用于在海量数据中字符串搜索/查找,查重/去重,或者查前缀的问题。
5、冒泡排序算法:
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:稳定
6、选择排序算法:
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:不稳定
7、插入排序算法:
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:稳定
8、快速排序算法:
时间复杂度:O(n log 2 n)----2为底数
空间复杂度:O(n log 2 n)----2为底数
稳定性:不稳定
9、归并排序算法:
(唯一一个外部排序,故如果遇到限制内存的排序问题第一个想到归并排)
时间复杂度:O(n log 2 n)----2为底数
空间复杂度:O(n)
稳定性:稳定
10、堆排序算法
时间复杂度:O(n log 2 n)----2为底数
空间复杂度:O(1)
稳定性:不稳定
啊啊啊 这篇就到这里吧,下次一定要界记得把优先级队列以及处理异常那一块更一下啊!