数据结构之二叉堆(构建堆,堆排序)-(七)

/*
 * @author Lip
 * @date 2015-04-23
 */
public class Heap
	{

		public static void main(String[] args)
			{
				// TODO Auto-generated method stub
				//System.out.println((int)-1.5);
				int []array={4,2,7,9,3,6,1,12,10,5};
				System.out.println("原始:");
				printHeapByLevel(array);
				System.out.println("最小堆:");
				getMinHeap(array);
				printHeapByLevel(array);
				//System.out.println(Math.log(i+1)/Math.log(2));

			   sort(array);
               printHeapByLevel(array);
			}
		/*
		 * 堆的性质(最小堆为例):
		 *    0.根节点为最小值
		 *    1.堆可以看做是一个完全二叉树(即孩子节点从左向右排列)
		 *    2.堆的高度lgn/lg2(n为节点的数目)
		 *    3.第i节点的左孩子节点是2*i+1,右孩子节点为2*i+2
		 *    4.以任意一个节点作为根节点,那么该节点都是堆
		 *    5.可以用一个数据来表示堆
		 */
		/*
		 * 构建堆的原理:
		 *   上滤
		 *   在最后一个节点后建立一个空节点,新插入的节点和父节点比较:
		 *      1,比父节点大,那么直接插入在这个空堆处
		 *      2,比父节点小,那么该父节点下移至该空节点
		 *      3,重复1,2直至插入堆中
		 */
		public static void getMinHeap(int []array)
		{
			for(int i=1;i<array.length;i++)
				insert(array, i);
		}
		//从插入第k个位置的值到堆中,插入一个的最坏情况就是lgN
		public static void insert(int []arrary,int k)
		{
			int insert=arrary[k];
			while(k>0)//一直和父节点比较
				{
					if(insert<arrary[(k-1)/2])//需要插入的元素小于该父节点,那么父节点下移
						{
						   arrary[k]=arrary[(k-1)/2];
						   k=(k-1)/2;
						   if(k==0)
							   arrary[k]=insert;
						}
					else //需要插入的元素大于该父节点,该节点正好可以插在最后一个位置
						{
							arrary[k]=insert;
						    break;
						}
				}
		}
		//按层次打印一个堆
		public static void printHeapByLevel(int []array)
		{
			int height=0;
			for(int i=0;i<array.length;i++)
				{
					int tempHeight=(int)(Math.log(i+1)/Math.log(2));
					if(tempHeight>height)
						{
						   System.out.println();
						   System.out.print(array[i]+" ");
						   height=tempHeight;
						}
					else
						System.out.print(array[i]+" ");
				}
			System.out.println();
		}
		/*
		 * 二叉树的排序
		 */
		public static void sort(int []array)
		{
			for(int i=0;i<array.length;i++)
				{
					deleteMin(array, array.length-1-i);
				}
		}
		/*
		 * 删除一个根节点,也就是最小值
		 * 那么子节点要上浮
		 * 可以根据此用堆排序
		 * 将删除的最小值放在数组的最后一个位置,节省空间
		 * 根节点为i(0,1,2,3...)
		 * 左孩子节点为:2*i+1
		 * 右孩子节点为:2*i+2
		 * n是剩下的节点
		 */
		public static void deleteMin(int []array,int n)
		{
			int min=array[0];
			int temp=0;//寻找一个孩子填充根节点
			while(2*temp+1<n)//无子节点
				{
					if(array[2*temp+1]>array[2*temp+2])
						{
						  array[temp]=array[2*temp+2];
						  temp=2*temp+2;
						}
					else
						{
						  array[temp]=array[2*temp+1];
						  temp=2*temp+1;
						}
				}
			//此刻temp为要空,要将最后一个节点值放在temp这个位置上,并且移动temp
			array[temp]=array[n];
			array[n]=min;
			if(temp<n)//要调整的节点后面还有节点
				insert(array, temp);
		}
	}

时间: 2024-12-15 20:12:22

数据结构之二叉堆(构建堆,堆排序)-(七)的相关文章

数据结构之二叉堆、堆排序

前言 上一篇写了数据结构之二叉搜索树.AVL自平衡树,这次来写堆. 堆的创造者 很久以前排序算法的时间复杂度一直是O(n^2), 当时学术界充斥着"排序算法不可能突破O(n^2)"的声音,直到1959年,由D.L.Shell提出了一种排序算法,希尔排序(Shell Sort),才打破了这种不可能的声音,把排序算法的时间复杂度提升到了O(n^3/2)! 当科学家们知道这种"不可能"被突破之后,又相继有了更快的排序算法,"不可能超越O(n^2)"彻底

D&amp;F学数据结构系列——二叉堆

二叉堆(binary heap) 二叉堆数据结构是一种数组对象,它可以被视为一棵完全二叉树.同二叉查找树一样,堆也有两个性质,即结构性和堆序性.对于数组中任意位置i上的元素,其左儿子在位置2i上,右儿子在左儿子后的单元2i+1中,它的父亲在[i/2](向下取整)中. 因此,一个数据结构将由一个数组.一个代表最大值的整数.以及当前的堆的大小组成.一个典型的优先队列(priority queue)如下: 1 #ifndef _BinHeap_H 2 struct HeapStruct; 3 type

Java数据结构之二叉搜索树

Java数据结构之二叉搜索树 1.二叉搜索树组成 二叉搜索树又称为二叉排序树,它或者是一颗空树,或者是一颗具有如下特性的非空二叉树,需要满足一下三个条件: (1)若它的左子树非空,则左子树上所有结点的关键字均小于根结点的关键字: (2)若它的右子树非空,则右子树上所有结点的关键字均大于(可以等于)根结点的关键字. (3)左子树右子树本身又各是一颗二叉搜索树 在算法描述中,均以结点值的比较来代表其关键字的比较,因为若结点的值为类类型时,该类必须实现系统提供的java.lang.comparable

【数据结构】二叉堆

看到一篇很好的博文,来自http://blog.csdn.net/morewindows/article/details/6709644 下面是博文内容 堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先讲解下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆).

数据结构 之 二叉堆(Heap)

注:本节主要讨论最大堆(最小堆同理). 一.堆的概念 堆,又称二叉堆.同二叉查找树一样,堆也有两个性质,即结构性和堆序性. 1.结构性质: 堆是一棵被全然填满的二叉树.有可能的例外是在底层.底层上的元素从左到右填入.这种树称为全然二叉树(complete binary tree).下图就是这样一个样例. 对于全然二叉树,有这样一些性质: (1).一棵高h的全然二叉树,其包括2^h ~ (2^(h+1) - 1)个节点.也就是说.全然二叉树的高是[logN],显然它是O(logN). (2).全然

优先队列 - 数据结构 (二叉堆)

优先队列包括二叉堆.d-堆.左式堆.斜堆.二项队列等 1.二叉堆 堆是一棵被完全填满的二叉树,有可能例外的是在底层,底层上的元素从左到右填入.这样的树称为完全二叉树. 堆序的性质:在一个堆中,对于每一个节点X,X的父亲的关键字小于(或等于)X中的关键字,根节点除外(它没有父节点).完全二叉树可以用数组实现. //关于二叉堆的头文件定义 如果要插入的元素是新的最小值,那么它将一直被推向堆顶.这样在某一个时刻,i将是1,我们就需要另Insert函数令程序跳出while循环,这个值必须保证小于或者至少

数据结构之二叉搜索树、AVL自平衡树

前言 最近在帮公司校招~~ 所以来整理一些数据结构方面的知识,这些知识呢,光看一遍理解还是很浅的,看过跟动手做过一遍的同学还是很容易分辨的哟~ 一直觉得数据结构跟算法,就好比金庸小说里的<九阳神功>,学会九阳神功后,有了内功基础,再去学习其他武功,速度就有质的提升 内容大概包含这些,会分多篇文章来整理: 二叉搜索树 平衡二叉树(AVL) 二叉堆 堆排序 四叉树 八叉树 图,深度优先DFS.广度优先BFS 最短路径 二叉树 二叉树,也就是每个节点最多有两个孩子的树.多用于搜索,查找,还有可以用来

C++实用数据结构:二叉索引树

看下面这个问题(动态连续和查询): 有一个数组A(长度为n),要求进行两种操作: add(i,x):让Ai增大x: query(a,b):询问Aa+Aa+1+...+Ab的和: 若进行模拟,则每次query操作的最坏的时间复杂度为O(n),在n较大时速度较慢.用前缀和也不能提高效率(每次add操作最坏为O(n)).有一种数据结构,可以在O(n)时间里初始化,用O(logn)的速度执行add操作或查询前缀和,从而执行query操作. 首先,我们来介绍“lowbit”.对于一个数x,lowbit(x

用Python实现数据结构之二叉搜索树

二叉搜索树 二叉搜索树是一种特殊的二叉树,它的特点是: 对于任意一个节点p,存储在p的左子树的中的所有节点中的值都小于p中的值 对于任意一个节点p,存储在p的右子树的中的所有节点中的值都大于p中的值 一个图例: 基于二叉搜索树的这种关系,我们可以用它来实现有序映射 遍历二叉搜索树 基于二叉搜索树的特性,采用中序遍历的方式可以使得遍历结果是按照从小到大的顺序排列的.了解中序遍历可以参考用Python实现数据结构之树 这里还需要思考的一个内容是在基于中序遍历的前提下,如何求一个节点的后继节点或前驱节