JAVA实现大顶堆的建立,删除以及排序

参考博客:
1.大顶堆的排序,插入,删除
2.图解堆排序
3.堆相关知识

1.堆的建立——建立大顶堆

思路:
 		1) 从最后一个节点的父节点(list.size()/2-1)开始,向下调整,建立大顶堆;
 		2) 比较父节点与孩子节点的大小:
 			2.1  若父节点小于左节点,将左节点跟父节点交换,继续向下调整。
 		    2.2  若父节点大于左节点,将左节点跟父节点交换,继续向下调整。
参数:
 		index:表示最初传进来的索引
 		size:表示集合的大小

相关代码:

/*
 * 调用建立大顶堆方法:
 * index:传入最后一个非叶子节点,即list.size()/2-1;
 * */
	for(int i = list.size()/2-1;i>=0;i--){
		buildHeap(list, i, list.size());
	}
	System.out.println( "输出建立的大顶堆数值:");	
	for(int i :list){
		System.out.print(i+" ");
	}
public static void buildHeap(List<Integer> list, int index,int size){
	int leftchild  = 2*index+1;
	int rightchild = 2*index+2;
	int temp = index;
	if(leftchild <size && list.get(index) < list.get(leftchild)){
		index = leftchild;
	}
	if(rightchild < size && list.get(index) < list.get(rightchild)){
		index = rightchild;
	}
	if(index!=temp){
		Collections.swap(list, temp, index);
		// 交换后继续向下调整,以index为父节点,继续向下调整
		buildHeap(list, index, size);
	}	
}

2.堆排序

 堆排序:
	1)将已经建立好的大顶堆,每次取出根节点,即最大值。 
	2)将最后一个节点的值赋给根节点,重新构建大顶堆。
	3)删除最后节点的数据,也即改变集合大小。

相关代码:

public static  void heapSort(List<Integer> list){
	for(int i = list.size()-1;i>=0;i--){
		Collections.swap(list, i, 0);
		// 从根节点向下调整,每次取出一个数值,集合长度逐渐减小
		buildHeap(list,0,i);
	}
}

3.删除大顶堆中的一个数值
相关代码

// 方法:删除大顶堆中的一个数据
public static void delete(List<Integer> list,int index){
	// 1.将最后一个节点,也即最后一个叶子节点的值(list.size()-1)赋给要删除数据的值
	list.set(index, list.get(list.size()-1));
	// 2.下沉操作,即向下判断赋值之后的数值与其孩子值的大小,从此处向下判断
	heapdown(list, index);
	// 3.删除最后一个叶子节点
	list.remove(list.size()-1);
} 
/*
 *    下沉操作:
 *    	1) 判断重新赋值的索引处(index)与其孩子大小
 * */
public static void heapdown(List<Integer> list,int index){
	int child = 2*index+1;
	int length = list.size()-1;
	while(child<length){
		if(child+1 <length &&list.get(child)<list.get(child+1)){
			child++;
		}
		if(list.get(index) > list.get(child)){
			break;
		}else{
			Collections.swap(list, child, index);
			heapdown(list, child);
		}
	}
}

4.完整代码:

import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;

public class HeapDeleteData {
public static void main(String[] args){
	List <Integer> list = new ArrayList<Integer>();
	Scanner sc = new Scanner(System.in);
	int n = sc.nextInt();
/*
 * 键盘输入长度为n的数据:
 * */
	for(int i =0;i<n;i++){
		list.add(sc.nextInt());
	}	
	System.out.println( "打印原始输入数据:");
	for(Integer i: list){
		System.out.print(i + " ");
	}
	System.out.println();
	
/*
 * 调用建立大顶堆方法:
 * index:传入最后一个非叶子节点,即list.size()/2-1;
 * */
	for(int i = list.size()/2-1;i>=0;i--){
		buildHeap(list, i, list.size());
	}
	System.out.println( "输出建立的大顶堆数值:");	
	for(int i :list){
		System.out.print(i+" ");
	}
	System.out.println();
	System.out.println( "对建立的大顶堆数值进行升序:");		
	heapSort(list);
	for(int i :list){
		System.out.print(i+" ");
	}
	System.out.println();
/*
 * 获取删除大顶堆中数值索引方法: 
 * */	
	System.out.println( "输入要删除数值:");
	int number = sc.nextInt(); 
	int index = getIndex(list, number);
	delete(list, index);
	
// 使用迭代器的方式输出集合中的元素	
	Iterator<Integer> iterator = list.iterator();
	System.out.println("删除数据后的大顶堆:");
	while(iterator.hasNext()){
		Integer in = iterator.next();
		System.out.print(in + " ");
	}
}

// 方法:建立大顶堆
	/*	思路:
	 * 		1) 从最后一个节点的父节点(list.size()/2-1)开始,向下调整,建立大顶堆;
	 * 		2) 比较父节点与孩子节点的大小:
	 * 			2.1  若父节点小于左节点,将左节点跟父节点交换,继续向下调整。
	 * 			2.2  若父节点大于左节点,将左节点跟父节点交换,继续向下调整。
	 * 参数:
	 * 		index:表示最初传进来的索引
	 * 		size:表示集合的大小
	 * 
	 * */
public static void buildHeap(List<Integer> list, int index,int size){
	int leftchild  = 2*index+1;
	int rightchild = 2*index+2;
	int temp = index;
	if(leftchild <size && list.get(index) < list.get(leftchild)){
		index = leftchild;
	}
	if(rightchild < size && list.get(index) < list.get(rightchild)){
		index = rightchild;
	}
	if(index!=temp){
		Collections.swap(list, temp, index);
		// 交换后继续向下调整,以index为父节点,继续向下调整
		buildHeap(list, index, size);
	}	
}

/*
 * 堆排序:
 *		1)将已经建立好的大顶堆,每次取出根节点,即最大值。 
 *		2)将最后一个节点的值赋给根节点,重新构建大顶堆。
 *		3)删除最后节点的数据
 * */
public static  void heapSort(List<Integer> list){
	for(int i = list.size()-1;i>=0;i--){
		Collections.swap(list, i, 0);
		// 从根节点向下调整,每次取出一个数值,集合长度逐渐减小
		buildHeap(list,0,i);
	}
}

// 方法:得到要删除数据的索引
public static int getIndex(List<Integer> list,int number){
	int index=-1;
	for(int i = 0; i < list.size();i++){
		if(list.get(i) == number){
			index = i;
			break;
		}
	}
	return index;
}
// 方法:删除大顶堆中的一个数据
public static void delete(List<Integer> list,int index){
	// 1.将最后一个节点,也即最后一个叶子节点的值(list.size()-1)赋给要删除数据的值
	list.set(index, list.get(list.size()-1));
	// 2.下沉操作,即向下判断赋值之后的数值与其孩子值的大小,从此处向下判断
	heapdown(list, index);
	// 3.删除最后一个叶子节点
	list.remove(list.size()-1);
} 

/*
 *    下沉操作:
 *    	1) 判断重新赋值的索引处(index)与其孩子大小
 * */
public static void heapdown(List<Integer> list,int index){
	int child = 2*index+1;
	int length = list.size()-1;
	while(child<length){
		if(child+1 <length &&list.get(child)<list.get(child+1)){
			child++;
		}
		if(list.get(index) > list.get(child)){
			break;
		}else{
			Collections.swap(list, child, index);
			heapdown(list, child);
		}
	}
}
}

5.样例输出:

7
1 2 3 4 5 6 7
打印原始输入数据:
1 2 3 4 5 6 7 
输出建立的大顶堆数值:
7 5 6 4 2 1 3 
对建立的大顶堆数值进行升序:
1 2 3 4 5 6 7 
输入要删除数值:
7
删除数据后的大顶堆:
1 2 3 4 5 6 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值