当前位置 博文首页 > ice_elephant的博客:数据结构算法之堆的应用

    ice_elephant的博客:数据结构算法之堆的应用

    作者:[db:作者] 时间:2021-09-16 15:49

    数据结构算法之堆

    堆的故事导入

    在这里插入图片描述

    比武招亲,为古代的招亲方式之一,由女方设下擂台,邀请公众参与,候选人以武功最好者 获得婚约。通常有两种形式:一是擂主由招亲的女生担任,谁挑战成功就成为新擂主。没人再比 试的话直接获得婚约;要是还有人比试,武功最好者获得婚约。二是自由擂主,武功最高者成为 擂主!
    这种擂台式的结婚有如下优点和缺点: 优点:可以找个猛男保镖保护,甚至一起闯荡江湖,四海为家 缺点: 不怕找个东方不败,就怕找个像同治帝一样的得了“怪病”

    堆的原理精讲

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    /*
    	加油!聂宗其!,高处不胜寒,岁寒知松柏。
    	
    	1、堆的初始化
    	2、堆的adjustDown
    	3、堆的adjustUp
    	4、堆的insert
    	5、堆的bulid
    	6、堆出列最大值
    	7、实现堆的前N个数的堆排列
    */
    
    #include<stdio.h>
    #include<Windows.h>
    
    #define DEFAULT_CAPICITY  128
    typedef struct _Heap{
    	int *arr;
    	int capcity;//容量
    	int size;	//当前元素的个数.数组形式即为下标减1
    	
    }Heap;
    
    bool initStack(Heap &heap,int size,int *original);
    void adjustDown(Heap &heap,int index);
    void adjustUp(Heap &heap,int index);
    void bulidStack(Heap &heap);
    bool insertdate(Heap &heap,int value);
    //初始化堆栈
    bool initStack(Heap &heap,int size,int *original){
    	int capcity = size>DEFAULT_CAPICITY?size:DEFAULT_CAPICITY;
    	
    	
    	heap.arr = new int[capcity];
    
    	heap.capcity = capcity;
    	heap.size=0;
    
    	if(!heap.arr) return false; 
    	
    	//初始化堆
    
    	if(size>0){
    	
    	heap.size = size;
    	memcpy(heap.arr,original,sizeof(int)*heap.size);
    
    	bulidStack(heap);
    	
    	
    	}
    	return true;
    }
    
    
    //将当前结点和它的兄弟结点创建堆
    void adjustDown(Heap &heap,int index){
    
    	if(index<0||index>heap.size) return ;
    	
    	int child,parent;
    	
    	//why not parent - index-1/2
    	//就是把当前结点当作是父结点,求子节点
    
    	for(parent = index;(2*parent+1)<heap.size;parent = child){
    		
    		child = parent*2+1;//根据传入
    
    		if(heap.arr[child+1]&&heap.arr[child]<heap.arr[child+1]){
    			child++;
    		}
    		
    		if(heap.arr[parent]<heap.arr[child]){
    
    			int tmp = heap.arr[parent];
    			heap.arr[parent] = heap.arr[child];
    			heap.arr[child] = tmp;
    			
    		}else{
    			break;
    			}
    
    
    		}
    
    	}
    
    //将当前结点和它的父节点调整为最大堆,
    void adjustUp(Heap &heap,int index){
    	
    	if(index<0||index>heap.size) return;
    
    	int parent ;
    	int child;
    
    	while(index>0){//这里的
    		parent = (index-1)/2;
    
    		if(parent<0) break;
    
    		child = index;
    		if(heap.arr[child]>heap.arr[parent]){
    			int tmp = heap.arr[parent];
    			heap.arr[parent] = heap.arr[child];
    			heap.arr[child] = tmp;
    			index = parent;
    
    		}else{
    			break;
    		}
    		
    	}
    
    }
    
    //建立堆,堆排序
    void bulidStack(Heap &heap){
    	//区别这里不是计算的parent = (i-1)/2他们两个不一样heap.size/2-1
    	for(int i = heap.size/2-1;i>=0;i--){
    		
    		adjustDown(heap,i);
    	}
    
    }
    
    //插入元素
    bool insertdate(Heap &heap,int value){
    
    	if(heap.size==heap.capcity) 
    	{
    		printf("元素已满,无法插入");
    		return false;
    	}
    
    	heap.arr[heap.size++] = value;
    	
    
    	adjustUp(heap,heap.size-1);//传入的是数组下标
    
    	return true;
    }
    
    //堆顶元素出列
    bool deleteTopdata(Heap &heap){
    	if(heap.size<=0) {
    		printf("无元素可出列!\n");
    	}
    
    	heap.arr[0] = heap.arr[heap.size-1];//就是把栈顶元素赋值为栈顶元素
    	heap.size--;						//将size减1
    	adjustDown(heap,0);
    	return true;
    
    }
    
    //实现堆中,查找出前N大的数
    void rankFrontN(Heap &heap,int N){
    	//N代表元素的个数
    	
    	if(!heap.arr) return; 
    
    	if(heap.size==0){
    		
    		printf("无元素可以排列!\n");
    		return ;
    
    	}
    
    	if(N>=heap.size){
    
    		printf("无效N值,N应小于%d!\n",heap.size);
    	
    	}
    	
    	for(int i=N/2-1;i>=0;i--){
    
    		adjustDown(heap,i);
    	
    		}
    
    	}
    
    int main(){
    	Heap hp;
    	int Orig[]={123,22,58,66,456,412,20,12};
    
    	if(initStack(hp,sizeof(Orig)/sizeof(Orig[0]),Orig)){
    	printf("堆初始化成功!\n");
    
    	}else{
    	printf("堆初始化失败!\n");
    	}
    
    	printf("排序前遍历******************\n");
    	for(int i=0;i<hp.size;i++){
    		printf("%d\t",hp.arr[i]);
    	}
    	printf("\n");
    	//bulidStack(hp);
    
    	printf("插入元素后遍历******************\n");
    	insertdate(hp,100);
    	insertdate(hp,10);
    	insertdate(hp,16);
    
    	for(int i=0;i<hp.size;i++){
    		printf("%d\t",hp.arr[i]);
    	}
    	printf("\n");
    
    
    	deleteTopdata(hp);
    
    	printf("除去栈顶元素后遍历******************\n");
    	for(