堆的操作——删除

672 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

删除操作

过程分析

首先我们给出函数的名字与参数。

int deleteheap( int heap[])

这里的删除指的是删除heap[1],也就是堆顶元素。

假设堆中情况如图所示:

image.png

我们可以知道heap[6]={6,1,3,4,8,7,6},len=6。

执行删除操作后,将heap数组的最后一位放到heap[0]中,len长度减一。

image.png

这时我们观察堆的结构,可以看出,6大于其子节点4与5。所以我们还需要再进行结构调整的工作。

将6下沉后,最终堆的结构如下图:

image.png

代码实现部分

1.删除子节点

heap[1]=heap[len];
	len--;

2.将新设置的堆顶结点下沉

	while(1){
		//循环退出条件 
		if(2*i>len){
			break;
		}
		if(heap[i]>heap[2*i] && heap[2*i]<heap[2*i+1]){
			temp=heap[i];
			heap[i]=heap[2*i];
			heap[2*i]=temp;
			i=2*i;
		}
		else if(heap[i]>heap[2*i+1] && heap[2*i+1]<heap[2*i]){
			temp=heap[i];
			heap[i]=heap[2*i+1];
			heap[2*i+1]=temp;
			i=2*i+1;
		}else
			break;
	}

函数代码综合

//删除第一个元素
int deleteheap( int heap[]){
	heap[1]=heap[len];
	len--;
	int temp;
	int i=1;
	while(1){
		//循环退出条件 
		if(2*i>len){
			break;
		}
		if(heap[i]>heap[2*i] && heap[2*i]<heap[2*i+1]){
			temp=heap[i];
			heap[i]=heap[2*i];
			heap[2*i]=temp;
			i=2*i;
		}
		else if(heap[i]>heap[2*i+1] && heap[2*i+1]<heap[2*i]){
			temp=heap[i];
			heap[i]=heap[2*i+1];
			heap[2*i+1]=temp;
			i=2*i+1;
		}else
			break;
	}
	return heap[1]; 
} 

堆操作的代码与结果展示

#include<stdio.h>
int heap[10]={5,1,3,4,5,7};
int len;

//向堆中插入x 
void insert( int x, int heap[]){
	int i=len+1;
	len++;
	heap[i]=x;
	while(i>1){
		if(heap[i]<heap[i/2]){
			int temp=heap[i];
			heap[i]=heap[i/2];
			heap[i/2]=temp;
		}
		else
			break;
		
		i=i/2;
	}
}

//更新pos处的元素为x
void update(int x, int pos, int heap[]){
	heap[pos]=x;
	int i=pos;
	while(1){
		//循环退出条件 
		if(i<=1||2*i>len){
			break;
		}
		
		int temp;
		//如果小于父节点就上飘 
		if(heap[i]<heap[i/2]){
			temp=heap[i];
			heap[i]=heap[i/2];
			heap[i/2]=temp;
			i=i/2;
		}else if( (heap[i]>heap[2*i]&&heap[2*i]<heap[2*i+1]) || 2*i+1>len ){//如果大于子节点就下沉 
			temp=heap[i];
			heap[i]=heap[2*i];
			heap[2*i]=temp;
			i=2*i;
		}else if(heap[i]>heap[2*i+1]&&heap[2*i+1]<heap[2*i]){
			temp=heap[i];
			heap[i]=heap[2*i+1];
			heap[2*i+1]=temp;
			i=2*i+1;
		}
	
	} 
	
} 
//删除第一个元素
int deleteheap( int heap[]){
	heap[1]=heap[len];
	len--;
	int temp;
	int i=1;
	while(1){
		//循环退出条件 
		if(2*i>len){
			break;
		}
		if(heap[i]>heap[2*i] && heap[2*i]<heap[2*i+1]){
			temp=heap[i];
			heap[i]=heap[2*i];
			heap[2*i]=temp;
			i=2*i;
		}
		else if(heap[i]>heap[2*i+1] && heap[2*i+1]<heap[2*i]){
			temp=heap[i];
			heap[i]=heap[2*i+1];
			heap[2*i+1]=temp;
			i=2*i+1;
		}else
			break;
	}
	return heap[1]; 
} 


//输出堆
void print(int heap[]){
	printf("len=%d\n",len);
	int i=1;
	while(i<=len){
		printf("%d ",heap[i++]);
	}
	printf("\n");
} 
int main(){

	len=5;
	printf("原始堆\n");
	print(heap);
	insert(2,heap);
	printf("添加操作后:\n"); 
	print(heap);
	update(6,3,heap); 
	printf("更新操作1后:\n");
	print(heap);
	update(8,4,heap);
	printf("更新操作2后:\n");
	print(heap);
	int now=deleteheap(heap);
	printf("删除操作后:\n");
	printf("堆顶元素:%d\n",now);
	print(heap);
	return 0;
} 

image.png