活动地址:CSDN21天学习挑战赛
📚“九层之台,起于垒土”。学习技术须脚踏实地。
☀️你要做冲出的黑马,而不是坠落的星星。
📖这里推荐一款刷题、模拟面试神器,可助你斩获心仪大厂offer:点我免费刷题、模拟面试
支持删除最大元素和插入元素的数据类型叫做优先队列。
对于数组来说,将最大的元素置于数组尾部,每次插入遍历数组,将所有较大的元素向移动,然后将要插入的元素置于应在的位置,就像插入排序一样。删除则仅需要将最大的元素删去即可。
对于链表,将最大的元素置于表头,每次插入遍历,找到对应结点插入,此过程需要维护两个指针,用于比较的指针与这个指针的前一个指针,用于插入。
对于数组来说,每次插入就将元素置于数组尾部,删除时则遍历数组,找到最大的与数组尾部的元素交换,并返回。
对于链表,每次插入将元素置于表头,删除时遍历,同样维护两个指针。
当一棵二叉树的每个结点都大于等于它的两个子结点时,它被称为堆有序。
二叉堆是一组能够用堆有序的完全二叉树排序的元素,并在数组中按照层级储存。
算法实现:
C++实现:
下面的算法将数组索引为 0 的位置空了出来,数组的长度为能存储最大元素数量加一。
template<typename T>
void sink(T* a, int k, size_t size){
while(2*k <= size){
int j = 2*k;
if(j < size && a[j] < a[j + 1])j++;
if(a[k] > a[j]) break;
swap(a[k], a[j]);
k = j;
}
}
template<typename T>
void swim(T* a, int k){
while(k > 1 && a[k/2] < a[k]){
swap(a[k/2], a[k]);
k = k/2;
}
}
template<typename T>
void insert(T* a, T t, int &size){
a[++size] = t;
swim(a, size);
}
template<typename T>
T delMax(T* a, int &size){
T max = a[1];
swap(a[1], a[size--]);
sink(a, 1, size);
return max;
}
通过上面的分析,不难得出:
数据结构 | 插入元素 | 删除最大元素 |
---|---|---|
有序数组或链表 | N | 1 |
无序数组或链表 | 1 | N |
堆 | logN | logN |
我们可以把优先队列变成一种排序方法,每次选取最大的元素,不断构造堆,就可以得到有序序列。
template<typename T>
void sink(T* a, int k, size_t size){
while(2*k <= size){
int j = 2*k;
if(j < size && a[j - 1] < a[j])j++;
if(a[k - 1] > a[j - 1]) break;
swap(a[k - 1], a[j - 1]);
k = j;
}
}
template<typename T>
void heapsort(T *a, size_t N){
for (int k = N / 2; k >= 1; k--) {
sink(a, k, N);
}
while (N > 1) {
swap(a[0], a[--N]);
sink(a, 1, N);
}
}
🚩本周的学习就到此结束啦,本周仍以复习经典排序算法为主,学习算法过程中动图有助于我们了解算法执行的过程当然自己画一遍试试坑会理解的更深。
✨要想超越别人的脚步,掌握比别人更多的知识!那就快来刷题吧:点我免费刷题、模拟面试
🌏我是博仔,期待你的关注,让我们一起进步!