算法之路_14、堆的基本操作

一、解释

在上一篇博文堆的预备知识 中,我们谈到,堆实际上可以理解为一个数组表示的完全二叉树。他也具有树的一些性质。在这一篇中主要来记录一些堆的基本操作。其中会涉及到上篇博文中阐述到的部分完全二叉树的性质。

二、代码

1、建立一个大根堆

大根堆是堆的两种形式之一。

根节点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆,又称最大堆(大顶堆)。

大根堆要求根节点的关键字既大于或等于左子树的关键字值,又大于或等于右子树的关键字值。

构建思路:

给我们一个任意的数组arr。将其调整为大根堆。操作如下:

a、以该数组为基础开始构建,起初默认堆大小为0,然后插入第一个元素arr[1],堆大小加一;

b、此时插入第二个元素(即数组的第二个元素)arr[1],堆大小加一,并对该元素做调整,大根堆的任意一个节点要小于其父节点元素。所以判断 arr[(1-1)/2](即父节点位置元素,这里计算方法在上篇博文中有阐述) 是否小于arr[1],若父节点元素比当前元素小,则交换。

c、插入第i+1个元素 判断 arr[(i-1)/2](即父节点位置元素) 是否小于arr[i],若父节点元素比当前 i  位置元素小,则交换,然后以父节点元素位置开始继续向上比较,直至小于某个元素,或到达堆顶停止。

代码如下:

	//构建大根堆  
	public static void heapInit(int[] arr){	
		for (int i = 0; i < arr.length; i++) {
			heapInsert(arr, i);			
		}
	}
	
	//插入数据 这里旨在将一个数组调整为大根堆 默认数据存储在数组中 index为要插入的数据的位置
	public static void heapInsert(int arr[],int index){
		//只要该元素大于他的父元素 则将该元素与父元素交换 并从父元素位置继续开始比较  
		while(arr[index]>arr[(index-1)/2]) {
			Sort_logarithmic_device.swap(arr, index, (index-1)/2);
			index=(index-1)/2;
		}
	}

2、堆元素调整

当某个堆中某个位置元素改变时,需要重新做调整,使其继续成为一个堆。

调整思路(当i位置元素改变时):

a、判断 已改变元素是否大于 父节点元素,若大于父节点元素则做建堆中的插入操作,即向上调整。

b、若该元素小于父节点元素,则将其与左右孩子中较大的元素做比较,若该元素最大,则结束。

若左右孩子中某个位置元素最大,则将最大元素位置与该元素位置交换,并将需要调整的位置改变,继续做上述操作。直至无左右孩子或已经为最大元素停止。

代码:

	//调整数据 调整index位置的元素 堆大小为heapSize 默认参数传入
	public static void heapify(int arr[],int index,int heapSize){
		//若需要调整位置的元素比父元素大 则向上调整 即同插入操作
		if (arr[(index-1)/2]<arr[index]) {
			heapInsert(arr, index);
		}else{//否则向下调整 
			while((index*2+1)<heapSize){//当左孩子存在时
				int left=index*2+1;//左孩子位置
				int largest=(left+1)<heapSize&&arr[left+1]>arr[left]
						?(left+1):left;//左右孩子较大一个元素位置 无右孩子时 最大为左孩子位置
				if (arr[largest]<arr[index]) {//当左右孩子最大元素小于需要调整的位置元素时 退出
					break;
				}
				//否则进行交换 并将需要调整的元素位置变为新位置 继续比较
				Sort_logarithmic_device.swap(arr, index, largest);
				index=largest;
			}
		}	
	}

3、弹堆顶操作

弹出堆顶实际就是删除操作。

算法思路:

a、将堆顶元素与堆最后一个位置元素交换,并堆大小减一,再对堆顶位置做调整操作。使得剩余元素依旧为一个堆。

代码:

	//弹出堆顶
	public static int deleteHeapTop(int arr[],int heapSize){
		int top=arr[0];
		Sort_logarithmic_device.swap(arr, 0, --heapSize);
		heapify(arr, 0, heapSize);
		return top;
	}
发布了56 篇原创文章 · 获赞 42 · 访问量 43万+

猜你喜欢

转载自blog.csdn.net/SIMPLE1995/article/details/86609276