堆基础
Posted futuresience
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆基础相关的知识,希望对你有一定的参考价值。
1 void siftdown(int i)//删除一个最小的数并新增一个数 2 {//传入一个需要向下调整的节点编号i, 3 int t,flag = 0; 4 while(i*2 <= n &&flag == 0) 5 { 6 if(h[i] > h[i*2])//判断左子 7 t = i*2; 8 else 9 t = i; 10 //如果他有右子,再对右子进行讨论 11 if(i*2+1 <= n) 12 { 13 if(h[t] > h[i*2+1]) 14 t = i*2+1; 15 } 16 if(t != i)//说明有更小的,发生了交换 17 { 18 swap(t,i); 19 i = t; 20 } 21 else 22 flag = 1;//说明该节点就是最小的,不再需要调整 23 } 24 } 25 26 void siftup(int i)//增加一个节点 27 { 28 int flag = 0; 29 if(i == 1) return; 30 while(i != 1 && flag == 0) 31 {//判断是否比父节点小 32 if(h[i] < h[i/2]) 33 swap[i,i/2];//交换它和它爸爸的位置 34 else 35 flag = 1;//表示已经不需要调整了,当前节点的值比父结点的值要大 36 i = i/2;//更新编号i为它父节点的编号,便于下一次向上继续调整 37 } 38 } 39 //建立最小堆 40 (1) 41 n = 0;//从空的堆开始,然后依次往堆中插入每一个元素 42 for(i = 1;i <= m;i++) 43 { 44 n++; 45 h[n] = a[i];//或者写成scanf("%d",&h[n]); 46 siftup(); 47 } 48 (2) 49 for(i = n/2;i>=1;i--)//直接将其放入数组中 50 siftdown(i);
注:建立最小堆。
堆排序(1)从大到小
1 #include <stdio.h> 2 int h[101]; 3 int n; 4 void swap(int x,int y) 5 { 6 int t; 7 t = h[x]; 8 h[x] = h[y]; 9 h[y] = t; 10 } 11 12 void siftdown(int i)//删除一个最小的数并新增一个数 13 {//传入一个需要向下调整的节点编号i, 14 int t,flag = 0; 15 while(i*2 <= n &&flag == 0) 16 { 17 if(h[i] > h[i*2])//判断左子 18 t = i*2; 19 else 20 t = i; 21 //如果他有右子,再对右子进行讨论 22 if(i*2+1 <= n) 23 { 24 if(h[t] > h[i*2+1]) 25 t = i*2+1; 26 } 27 if(t != i)//说明有更小的,发生了交换 28 { 29 swap(t,i); 30 i = t; 31 } 32 else 33 flag = 1;//说明该节点就是最小的,不再需要调整 34 } 35 } 36 void creat() 37 { 38 int i; 39 for(i = n/2;i >= 1;i--) 40 siftdown(i); 41 } 42 void headsort()//核心代码 43 { 44 while(n > 1) 45 { 46 swap(1,n); 47 n--; 48 siftdown(1); 49 } 50 } 51 52 int main () 53 { 54 int i,num; 55 scanf("%d",&num); 56 for(i = 1;i <= num;i++) 57 scanf("%d",&h[i]); 58 n = num; 59 creat(); 60 headsort(); 61 for(i = 1;i <= num;i++) 62 printf("%d ",h[i]); 63 64 return 0; 65 }
(2)从小到大
1 #include <stdio.h> 2 int h[101]; 3 int n; 4 5 void swap(int x,int y) 6 { 7 int t; 8 t = h[x]; 9 h[x] = h[y]; 10 h[y] = t; 11 } 12 13 void siftdown(int i)//删除一个最小的数并新增一个数 14 {//传入一个需要向下调整的节点编号i, 15 int t,flag = 0; 16 while(i*2 <= n &&flag == 0) 17 { 18 if(h[i] > h[i*2])//判断左子 19 t = i*2; 20 else 21 t = i; 22 //如果他有右子,再对右子进行讨论 23 if(i*2+1 <= n) 24 { 25 if(h[t] > h[i*2+1]) 26 t = i*2+1; 27 } 28 if(t != i)//说明有更小的,发生了交换 29 { 30 swap(t,i); 31 i = t; 32 } 33 else 34 flag = 1;//说明该节点就是最小的,不再需要调整 35 } 36 } 37 38 void creat() 39 { 40 int i; 41 for(i = n/2;i >= 1;i--) 42 siftdown(i); 43 } 44 45 int deletemax()//核心代码 46 { 47 int t; 48 t = h[1];//临时变量用来记录堆顶点的值 49 h[1] = h[n];//将堆的最后一个顶点赋值到顶点 50 n--;//堆的元素减少一 51 siftdown(1);//向下调整 52 53 return t;//返回之前记录的堆顶点的最大值 54 } 55 int main (void) 56 { 57 int i,num; 58 scanf("%d",&num); 59 for(i = 1;i <= num;i++) 60 scanf("%d",&h[i]); 61 n = num; 62 creat(); 63 for(i = 1;i <= num;i++) 64 printf("%d ",deletemax()); 65 66 return 0; 67 }
1 void heapfy(int a[],int i,int heapsize)//建立最大堆 2 { 3 int largest=i; 4 int left=2*i+1; 5 int right=left+1; 6 if(left<heapsize && a[i]<a[left]) 7 largest=left; 8 if(right<heapsize && a[largest]<a[right]) 9 largest=right; 10 if(largest!=i) 11 { 12 swap(a[i],a[largest]); 13 heapfy(a,largest); 14 } 15 } 16 17 void buildheap(int a[],int len) 18 { 19 for(int i=len/2-1;i>=0;i--) 20 heapfy(a,i,len); 21 } 22 23
以上是关于堆基础的主要内容,如果未能解决你的问题,请参考以下文章
[vscode]--HTML代码片段(基础版,reactvuejquery)