欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(2.19)数据结构

程序员文章站 2022-06-30 09:09:36
...

性质:儿子的值一定不小于父亲的值,树的结构是从上到下,从左到右紧凑排列的。

插入数值:先在末尾插入该数值,然后不断向上提升直到没有大小颠倒为止。
(2.19)数据结构
删除最小值:首先把堆的最后一个节点的数值复制到根节点上,并且删除最后一个节点。然后不断向下交换直到没有大小颠倒为止。在向下交换的过程中,如果有2个儿子,那么选择数值较小的儿子(如果儿子比自己小的话)进行交换。
(2.19)数据结构

时间复杂度:堆的两种操作所花的时间与树的深度成正比,n个元素的时间复杂度是O(logn)

堆的实现:
给每个节点赋予一个编号,用数组来存储
左儿子的编号是自己的编号x2 + 1
右儿子的编号是自己的编号x2 + 2
(2.19)数据结构

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
 
const int MAX_N = 1000;
int heap[MAX_N];
int sz = 0; 

void push(int x){
	// 自己节点的编号
	int i = sz ++;
	
	while(i > 0){
		// p是父亲节点的编号
		int p = (i - 1) / 2;
		
		// 如果已经没有大小颠倒则退出循环
		if(heap[p] <= x)
			break;
		
		//把父亲节点的数值放到儿子节点位置上,并存储父亲节点索引
		heap[i] = heap[p];
		i = p; 
	}
	heap[i] = x; 
}

int pop(){
	// 最小值
	int ret = heap[0];
	
	//x 为要放到根节点的数值
	int x = heap[--sz];
	
	// 从根开始向下交换
	int i = 0;
	while(i*2 + 1 < sz){
		// 比较两个儿子的值
		int a = i*2 + 1;
		int b = i*2 + 2;
		if(b < sz && heap[b] < heap[a])
			a = b;
		
		// 如果已经没有大小颠倒则退出
		if(heap[a] >= x)
			break;
		
		//把儿子的数值提上来
		heap[i] = heap[a];
		i = a;
	} 
	heap[i] = x;
	return ret;
}
void printheap(){
	for(int i = 0 ; i < sz ; i ++)
		printf("%d ", heap[i]);
	printf("\n");
}
void solve(){
	push(1);
	printheap(); 
	push(2);
	printheap();
	push(4);
	printheap();
	push(7);
	printheap();
	push(8);
	printheap();
	push(5);
	printheap();
	int a = pop(); // 1
	printheap();					 
} 	


int main(){	
	solve(); 
	return 0;
}

优先队列(STL)

优先输出最大的元素

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
 
void solve(){
	priority_queue<int> pque;
	
	pque.push(3);
	pque.push(5);
	pque.push(1);
	
	while(!pque.empty()){
		// 获取并删除最大值
		cout << pque.top() << endl;  // 5 3 1
		pque.pop(); 
	}	 
} 	


int main(){	
	solve(); 
	return 0;
}

优先输出最小的元素

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
 
void solve(){
	priority_queue<int, vector<int>, greater<int> > pque;
	
	pque.push(3);
	pque.push(5);
	pque.push(1);
	
	while(!pque.empty()){
		// 获取并删除最小值
		cout << pque.top() << endl; // 1 3 5
		pque.pop(); 
	}	 
} 	


int main(){	
	solve(); 
	return 0;
}
相关标签: 算法