堆排序aa

父节点为i ——>左孩子2*i+1,右孩子2*i+2

子——>父:(i-1)/2

注意:升序用大根堆,降序用小根堆

堆排序是不稳定的排序,空间复杂度为O(1),平均时间复杂度是(nlogn)

大根堆:每个节点的值都小于或等于它的左右孩子的节点  最大的值就是堆顶的元素

 思想:将顶端的数与末尾的数交换,此时,末尾的数为最大值,剩余待排序数的个数为n-1

将剩余的n-1个数在构造成大根堆,反复执行,便能得到有序数组

如何构造大根堆:从最后一颗子树开始,从后往前调整,每次调整,从上往下调整,调整为大根堆

堆排序aa_第1张图片

最后一层第一个节点的索引为:节点总数/2,也就是第一个叶子节点 最后一个费叶子节点就是最后一个叶子节点所有-1,找到最后一个非叶子节点,比较它的左右节点中最大的一个值,是否比它大,如果比他大就交换位置,然后找到下一个非叶子节点,重复此操作

小根堆:~  


代码 下标是从0开始的
#include
using namespace std;
void AdjustDown(int* arr, int n, int root) {
    int parent = root;
    while ((parent << 1) + 1 < n) {
        int child = (parent << 1) + 1;
        if (child + 1 < n && arr[child + 1] < arr[child])child++;
        if (arr[child] < arr[parent])swap(arr[child], arr[parent]);
        else break;
        parent = child;
    }
}
void HeapSort(int* arr, int n) {
    for (int i = (n - 1 - 1)/2; i >= 0; i--) {
        AdjustDown(arr, n, i);
    }
    int end = n-1;
    while (end >= 0) {
        swap(arr[0], arr[end]);
        AdjustDown(arr, end, 0);
        end--;
    }
};
void print_arr(int* arr,int n) {
    for (int i = 0; i         cout << arr[i] << " ";
    }
}
int main() {
    int arr[] = { 1,9,2,8,3,7,4,6,5,10 };
    int n = sizeof(arr) / sizeof(arr[0]);
    HeapSort(arr, n);
    print_arr(arr,n);
    return 0;
}

一些操作

插入

void push(int x){//要插入的数 
	heap[++siz]=x;
	now=siz;
	//插入到堆底 
	while(now){//还没到根节点,还能交换 
		ll nxt=now>>1;//找到它的父亲 
		if(heap[nxt]>heap[now])swap(heap[nxt],heap[now]);//父亲比它大,那就交换 
		else break;//如果比它父亲小,那就代表着插入完成了 
		now=nxt;//交换 
	}
	return; 
}

while条件改为now!=1 

删除操作
 

void pop(){
	swap(heap[siz],heap[1]);siz--;//交换堆顶和堆底,然后直接弹掉堆底 
	int now=1;
	while((now<<1)<=siz){//对该节点进行向下交换的操作 
    	int nxt=now<<1;//找出当前节点的左儿子 
        if(nxt+1<=siz&&heap[nxt+1]

 

 查询的话就是第一个元素了

priority_queueq;//这是一个大根堆       默认是递减的  第一个元素就是最大的

priority_queue, greater>q;//这是一个小根堆      默认是递增的,第一个元素是最小的

q.top()//取得堆顶元素,并不会弹出
q.pop()//弹出堆顶元素
q.push()//往堆里面插入一个元素
q.empty()//查询堆是否为空,为空则返回1否则返回0
q.size()//查询堆内元素数量

你可能感兴趣的:(数据结构,算法)