1,思考一种实现优先级队列的方式
①建立一个链表, 在表头以O(1)的复杂度插入操作,然后遍历该链表删除最小元O(N)
②建立一个链表, 每次插完进行排序, 然后delete 最小元
当然用二叉查找树也可以
今天介绍一种时间复杂度较低的手法----堆
堆是一颗完全被填满的二叉树. 只有在底层的时候从左到右没填满.
同时这样的树也被称为完全二叉树.
2.树这种数据结构在数组中应该如何表示呢?
A | B | C | D | E | F | G | H | I | J | K | ||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
①对于数组任意 i 位置的元素, 左儿子在 2i ,右儿子在2i + 1
3,堆的性质及基本操作
堆的每个节点都小于等于他的两个儿子,这也的堆叫做最小堆
①优先级队列的声明
struct HeapStruct{
int capacity;
int size;
int* nums;
}
Heapstruct HeapCreate(int max){
Heapstruct h = malloc(sizeof(Heapstruct));
h->nums = malloc(sizeof(int)*(max + 1));
h->capacity = max;
h->size = 0;
}
②insert demo
void Insert(Heapstruct h, int val){
if(h->size == h->capacity){
return;
}
for(int i = ++h->size; h->nums[i/2] > val;i /= 2){
h->nums[i] = h->nums[i/2];
}
h->nums[i] = val;
}
③delete demo
int DeleteMin(Heapstrcut h){
if(h->size == 0){
return -1;
}
minval = h->nums[1];
lastval = h->nums[h->size--];
int i;
for(i = 1;i*2 <= h->size;i = child){
child = i * 2;
if(child != h->size && h->nums[child] > h->nums[child + 1]){
child++;
}
if(lastval > h->nums[child]){
h->nums[i] = h->nums[child];
}
}
h->nums[i] = lastval;
return minval;
}
至此为止,基本的堆操作已经学会了,开始愉快的做题吧~
1,任务调度器
2,前k个高频元素
4,合并K个升序链表
5,滑动窗口最大值