建堆,以及对堆排序

建堆,以及堆排序

代码1:

#include<stdio.h>
int h[101];//用来存放堆的数组
int n;//用来存储堆中元素的个数,就是堆的大小
//交换函数,用来交换堆中的俩个元素的值
void swap(int x,int y)
{
	int t;
	t=h[x];
	h[x]=h[y];
	h[y]=t;
}
//向下调整函数
void siftdown(int i)
{//传入一个须要向下调整的的节点编号i,这里传入1。即从堆的顶点開始向下调整
	int t,flag=0;//flag用来标记是否须要继续向下调整
	//当i节点有儿子(事实上是至少有左儿子)而且有须要继续调整的时候循环就运行
	while(i*2<=n&&flag==0)
	{
		//首先推断它与左儿子的关系。而且t记录值比較小的节点编号
		if(h[i]>h[i*2])
		{
			t=i*2;
		}
		else
	    {
	    	t=i;
		}
		//假设它有右儿子,再对右儿子进行讨论
		if(i*2+1<=n)
		{
			//假设右儿子的值更小。更新较小的节点编号
			if(h[t]>h[i*2+1])
			{
				t=i*2+1;
			}
		}
		//假设发现最小的结点编号不是自己,说明子结点中有比父节点更小的值
		if(t!=i)
		{
			swap(t,i);//交换他们。注意swap函数
			i=t;//更新i为刚才与它交换的儿子结点的编号。便于接下来继续向下调整
		}
		else
		{
			flag=1;
			//否则说明当前的父结点已经比俩个子结点都要小了,不须要再进行调整
		}
	}
}
//建立堆函数
void creat()
{
	int i;
	for(i=n/2;i>=1;i--)
	{
		//总最后一个非叶结点到第一个结点一次进行向上调整
		siftdown(i);
	}
}
//删除最大的元素
int deletemax()
{
	int t;
	t=h[1];//用一个暂时变量记录堆顶点的值
	h[1]=h[n];//将堆的最后一个点赋值给堆顶
	n--;//堆的元素降低1
	siftdown(1);//向下调整
	return t;//返回之前记录的堆的顶点的最大值
}
int main()
{
	int i,num;
	scanf("%d",&num);
	for(i=1;i<=num;i++)
	{
		scanf("%d",&h[i]);
	}
	n=num;
	creat();
	for(i=1;i<=num;i++)
	{//删除顶部元素,连续删除n次,事实上也就是从大到小的把数输出
		printf("%d ",deletemax());
	}
	return 0;
}

代码,2:

#include<stdio.h>
int h[101]; //用来存储堆的数组
int n;//用来存储堆中的元素的个数,也就是堆的大小
//交换函数,用来交换堆中的俩个元素的值
void swap(int x,int y)
{
	int t;
	t=h[x];
	h[x]=h[y];
	h[y]=t;
}
//向下调整函数
void siftdown(int i)
{//传入一个须要向下调整的的节点编号i,这里传入1,即从堆的顶点開始向下调整
	int t,flag=0;//flag用来标记是否须要继续向下调整
	//当i节点有儿子(事实上是至少有左儿子)而且有须要继续调整的时候循环就运行
	while(i*2<=n&&flag==0)
	{
		//首先推断它与左儿子的关系,而且t记录值比較小的节点编号
		if(h[i]<h[i*2])
		{
			t=i*2;
		}
		else
	    {
	    	t=i;
		}
		//假设它有右儿子。再对右儿子进行讨论
		if(i*2+1<=n)
		{
			//假设右儿子的值更大,更新较小的节点编号
			if(h[t]<h[i*2+1])
			{
				t=i*2+1;
			}
		}
		//假设发现最小的结点编号不是自己,说明子结点中有比父节点更小的值
		if(t!=i)
		{
			swap(t,i);//交换他们,注意swap函数
			i=t;//更新i为刚才与它交换的儿子结点的编号。便于接下来继续向下调整
		}
		else
		{
			flag=1;
			//否则说明当前的父结点已经比俩个子结点都要小了,不须要再进行调整
		}
	}
}
//建立堆函数
void creat()
{
	int i;
	for(i=n/2;i>=1;i--)
	{
		//总最后一个非叶结点到第一个结点一次进行向上调整
		siftdown(i);
	}
}
//堆排序
void heapsort()
{
	while(n>1)
	{
		swap(1,n);
		n--;
		siftdown(1);
	}
 }
 int main()
 {
 	int i,num;
 	scanf("%d",&num);
 	for(i=1;i<=num;i++)
 	{
 		scanf("%d",&h[i]);
	}
	n=num;
	creat();//建堆
	heapsort();//堆排序
	for(i=1;i<=num;i++)
	{
		printf("%d ",h[i]);
	 }
	 return 0;
 }
时间: 2024-10-25 19:40:15

建堆,以及对堆排序的相关文章

Python3实现最小堆建堆算法

今天看Python CookBook中关于“求list中最大(最小)的N个元素”的内容,介绍了直接使用python的heapq模块的nlargest和nsmallest函数的解决方式,记得学习数据结构的时候有个堆排序算法,所以顺便研究了一下“堆”结构(这里特指二叉堆). 概念 所谓二叉堆(binary heap)实际上就是一颗特殊的完全二叉树,其特殊性在于: 二叉树中所有的父节点的值都不大于/不小于其子节点: 根节点的值必定是所有节点中最小/最大的. 父节点值不大于子节点且根节点值最小称为最小堆

建堆复杂度O(n)证明

堆排序中首先需要做的就是建堆,广为人知的是建堆复杂度才O(n),不过很少有人去了解过这个复杂度的证明过程,因为不是那么直观地可以一眼就看出来.本文不讲堆排序,只单纯讲建堆过程. 建堆代码 欲了解复杂度的计算过程,必先看懂建堆代码.先看这个建堆过程 // 将arr[n]向上调整至合适位置 void AdjustHeap(vector<int> &arr, int n) { if(n<=0) return ; if(arr[(n-1)/2] > arr[n]) { //与父结点

堆+建堆、插入、删除、排序+java实现

package testpackage; import java.util.Arrays; public class Heap { //建立大顶堆 public static void buildMaxHeap(int[] a) { for(int i=(a.length/2)-1;i>=0;i--) { adjustDown(a,i,a.length); } } //向下调整 public static void adjustDown(int[] a,int i,int len) { int

自下而上建堆(heap)的时间复杂度证明

作者:Tobin 日期:2019/04/13 缘由:看python cookbook时,用到了heapq的库,书中提到,如果仅仅是返回一个数组的最大值,用max就可以了,但是如果返回多个较大或者较小元素用堆,如果返回的个数接近于数组本身的元素个数时,直接用排序即可.那么我在想,为啥返回几个元素的时候用堆效果比较好呢?于是我翻开了尘封许久的<算法导论>. 什么是堆 堆是一种数据结构.二叉堆是一个数组,近似于一个完全二叉树.树上的每个结点对应于数组的一个元素,除了最底层外树是充满的.下面的图是一个

建堆[HihoCoder-1405]

Building Heap HihoCoder-1405 hihoCoder太阁最新面经算法竞赛11 问题大意:给定一个$N$个元素的数组$A$(元素互不相同),要求你建立满足下列要求的二叉树$T$,并输出其前序遍历: 1)$T$满足最小堆性质: 2)输入的数组$A$满足$T$的中序遍历. 这是一道数据结构基础题,主要是解决如何建堆.题目要求最小堆,其树根必然是整个树的最小值.因此在建堆过程中,只需寻找最小值,根据找到的最小值的位置将中序遍历的序列一分为二,继续对这两个子序列建堆,直到子序列没有

c++ 堆的创建 堆排序

#pragma once #include<iostream> #include<vector> using namespace std; class BigHeap//仿函数类  大堆返回true { public: bool operator()() { return true; } }; class SmallHeap//仿函数类  小堆返回false { public: bool operator()() { return false; } }; template <

大顶堆第二弹----堆排序(递归实现)

1 package tooffer; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 6 public class BigHeap { 7 8 9 10 /* 11 *交换堆中的两个元素 12 */ 13 private void swap(ArrayList<Integer> heapList,int srcIndex,int dstIndex) 14 { 15 int tmp = heapList.get(srcIn

C语言实现数据结构中的堆创建,堆排序

#include "stdio.h"#include "stdlib.h"void swap(int *a,int *b)//交换两个数{int t;t=*a;*a=*b;*b=t;}void minheap(int *a,int i)    //小根堆的调整,在i节点向上调整,根据一个所给的数组,对数组进行小根堆的创建{ int temp,j; temp=a[i]; j=(i-1)/2;                         //i节点的父节点 whil

堆结构与堆排序

#ifndef HEAP_H #define HEAP_H #include <iostream> #include <vector> using namespace std; template <typename T> class Heap { public: Heap(vector<T> &_vec) : vec(_vec){} ~Heap(){ vec.~vector(); } Heap(const Heap& rhs) { this-