堆排序 java

对于下面的二叉树进行堆排序

                 

/*
*           a
*         /   \
*        b     c
*       /\    / \
*      d  e  f   g
*
*
*/

1 。 首先我们先把c 与 f , g 进行比对,如果c> f  且 c>g    进入 操作2 ,  如果 c<f 或  c<g 我们将  c与最大的那个节点进行交换 (我们的目的是把二叉树中最大的数移动到跟节点)

2 。 对于b 进行操作1 

3 。 对a 进行操作1 ( 这样最大的数被移动到跟节点)  ,  将这个最大数 与二叉树最后的一个数字进行交换  , 二叉树的尺寸减少1 , 对除了最后节点外的二叉树重复前面的操作



让我们来举个 栗子


/*
*           4
*         /   \
*        2     10
*       /\    / \
*      6  7  1   20
*
*
*/


进行第一步 对10进行判断,得到下面的堆


/*
*           4
*         /   \
*        2     20
*       /\    / \
*      6  7  1   10
*
*
*/


然后对2 进行操作


<pre name="code" class="java">/*
*           4
*         /   \
*        7     20
*       /\    / \
*      6  2  1   10
*
*
*/

 



对 4 进行判断


/*
*           20
*         /   \
*        7     4
*       /\    / \
*      6  2  1   10
*
*
*/

这个时候我们得到当前堆的最大值20  将它与最末的节点交换


/*
*           10
*         /   \
*        7     4
*       /\    / \
*      6  2  1   20
*
*
*/


接下来我们查看除了 20节点的其他的堆,同样,因为4不是最下层节点,从4开始判断,因为4大于1(不考虑20)所以不变。

查看7节点,7节点大于2和6,所以不变。

查看10节点,同样 10节点不变。

将10与1交换(与最后的节点交换)得到下图

/*
*           1
*         /   \
*        7     4
*       /\    / \
*      6  2  10   20
*
*
*/

然后从7开始查看  , 对于剩下的堆我们还有5个元素要查看,而从那个节点开始查看 我是用    节点数 / 2  得到的值开始查看。

  对于这个堆剩下 1,7,4,6,2.  那个用5 / 2 得到2  所以从第二个节点开始查看。

对于7来说,不用变。

继续查看1节点得到下图

/*
*           7
*         /   \
*        1     4
*       /\    / \
*      6  2  10   20
*
*
*/


接下来 交换7 与 2

/*
*           2
*         /   \
*        1     4
*       /\    / \
*      6  7  10   20
*
*
*/

剩下4个节点  4 / 2  = 2  所以从1 开始查看

用1 与6 交换

/*
*           2
*         /   \
*        6     4
*       /\    / \
*      1  7  10   20
*
*
*/

查看2 节点  将 2与 6 交换


/*
*           6
*         /   \
*        2     4
*       /\    / \
*      1  7  10   20
*
*
*/

6与最后节点交换

/*
*           1
*         /   \
*        2     4
*       /\    / \
*      6  7  10   20
*
*
*/

这个时候我们还剩下3个节点,3 / 2  = 1   所以查看第一个节点,也就是1 得到下图

/*
*           4
*         /   \
*        2     1
*       /\    / \
*      6  7  10   20
*
*
*/

将4与 最后节点交换 得到下图

/*
*           1
*         /   \
*        2     4
*       /\    / \
*      6  7  10   20
*
*
*/

查看1节点  得到下图

/*
*           2
*         /   \
*        1     4
*       /\    / \
*      6  7  10   20
*
*
*/


然后交换


/*
*           1
*         /   \
*        2     4
*       /\    / \
*      6  7  10   20
*
*
*/

这个时候还有最后一个元素, 1 / 2 = 0   所以算法结束  下面是java 代码



/**
 * 
 * @author rq
 *
 */

public class Heap {
static	 int[] arr={0,13,65,5,97,25,7,37,22,2,4,28};
 // bottom-up heap algorithm
static int size;
	public Heap(int size){
		int address = size/2;
		createTree(address);
	}
	public class Node{
		Node node;
		Node left;
		Node right;
		int value;
		public void node(int value){
			this.value=value;
		}
	}
	
	public void createTree(int address){
		
	if(address>0){	
		if(2*address+1<=size){
			exchangeValue(2*address,2*address+1,address);
		}else{
			exchangeValue(2*address,2*address,address);
		}
		createTree(address-1);
	}
	
	bottomupHeap(size);
}
	
	
	public void exchangeValue(int left,int right, int node){
		int c;
		if(arr[left]>=arr[right]){
			c=left;
		}else{
			c=right;
		}
		if(arr[c]>arr[node]){
		int exValue=arr[c];
		arr[c]=arr[node];
		arr[node]=exValue;
		}
	}
	public void bottomupHeap(int l){
		if(l>1){
		int exValue=arr[1];
		arr[1]=arr[l];
		arr[l]=exValue;
		size=l-1;
		int address=size/2;
		createTree(address);
		}
	}
	
	/** 
     *                   13
     *                 /    \
     *               65      5
     *              /  \    /  \
     *            97    25 7   37
     *           /  \  /  \   
     *         22   2  4  28 
     */
    public static void main(String[] args) {
       
        size=arr.length-1;
        new  Heap(size);
        for(int i=1;i<=arr.length-1;i++){
        System.out.print(arr[i]+"   ");
        }
    }
}



   转载请注明  谢谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值