左神算法基础class2——题目3 堆heapInsert、heapify、堆排序C++实现
1.基础知识
1.完全二叉树有两种:
5
/ \
1 2
/ \ /
3 4 2 6
满二叉树
5
/ \
1 2
/
1
从左到右排序的二叉树
2.完全二叉树可等价为堆,堆可用数组实现
其中第i结点的左孩子:2i+1,第i结点的右孩子:2i+2,第i结点的父节点:(i-1)/2
3.大根堆:指任意子树的最大值是其头部的结点
小根堆:指任意子树的最小值是其头部的结点
2.heapInsert:新结点加入进来并向上调整为大根堆的过程
把数组变为大根堆,建立堆结构
分析
如果当前插入的元素大于其父节点的元素,那么交换父节点与当前节点的位置。接着考察更换结点后的插入元素与新位置的父节点大小,如果还是大于还要继续交换。
eg。例[2,1,3,6]变换为大根堆
位置0,1,2,3
(1)2插入,父节点(0-1)/2 = 0位置,自己和自己不动;
(2)1插入,父节点(1-1)/2 = 0位置,1<2,不动;
(3)3插入,父节点(2-1)/2 = 0位置,3>2,交换位置;此时3的位置变为0,父节点(0-1)/2 = 0位置,自己和自己不动;
此时:
3
/
1 2
(4)6插入,父节点(3-1)/2 = 1位置,6>1,交换位置;此时6的位置变为1,父节点(1-1)/2 = 0位置;6>3,继续交换;
6
/
3 2
/
1
核心代码
(index-1)/2是index父节点的位置
void heapinsert(int arr[],int index)
{
while(arr[index] > arr[(index-1)/2])
{
swap(arr[index],arr[(index-1)/2]);
index = (index-1)/2;
}
}
使用for循环遍历数组,调用heapinsert
for(int i = 0;i < length;i++ )
{
heapinsert(arr,i);//用for循环传入要处理的index
}
完整代码
#include<iostream>
#define length 5
using namespace std;
void swap(int &a,int &b)
{
int temp = a;
a = b;
b = temp;
}
void heapinsert(int arr[],int index)
{
while(arr[index] > arr[(index-1)/2])
{
swap(arr[index],arr[(index-1)/2]);
index = (index-1)/2;
}
}
int main()
{
//int arr[length] = {2,1,3,6,0,4};
int arr[length] = {
3,4<