堆排序
来源:互联网 发布:php soap header 验证 编辑:程序博客网 时间:2024/06/16 16:30
一 初识堆
堆 数据结构是一种数组,它可以视为一颗完全二叉树。如下图:
图中的树是数组,A={16, 14, 10, 8, 7, 9, 3, 7},圈内表示数值,圈外红色的数字表示数组的下标。
array_size是数组的大小(此时是8),heap_size是构建堆的元素的多少。满足heap_size<= array_size
给定某结点的下表i,其父结点下标为PARENT(i), 左儿子下标为LEFT(i), 右儿子下标为RIGHT(i)。满足
PARENT(i) = int((i-1)/2) ; LEFT(i) = 2*i+1; RIGHT(i)=2*i+2
最大堆满足:对于任何结点(除根节点)PARENT(i) > i
最小堆满足:对于任何结点(除根节点)PARENT(i) <i
叶子节点(下标):int(i/2), int(i/2)+1......array_size
下面的介绍以最大堆为例
二 保持堆的性质
最大堆的性质为 PARENT(i) > i,因此对于特定的结点,应满足比左右儿子都大
、
在上图中下标为1的结点值为2,左孩子为4,右孩子为1,1结点比左孩子小,就让1结点和3结点数值换过来。若此时4结点大于4,就把1结点和4结点数值换过来。
参考程序:
void MAX_HEAPIFY(int *A, int heap_size, int i) //i 为待处理保持性质的结点下标{ int l = 2 * i + 1; //左孩子 int r = 2 * i + 2; //右孩子 int largest, tmp; if(l < heap_size && A[i] < A[l]) // 左孩子数值大 { largest = l; } else //左孩子数值不大 { largest = i; } if(r < heap_size && A[largest] < A[r]) //右孩子数值大
{ largest = r; } if(largest != i) { tmp = A[i]; A[i] = A[largest]; A[largest] = tmp; MAX_HEAPIFY(A, heap_size, largest); //再从数值大的结点继续往下递归处理 }}
三 构建堆
从底向上使得每个结点保持堆的性质就可以构建堆,因为叶子节点就自己,无儿女,因此从倒数第一个非叶子节点开始依次往上构建,直到树根位置,而叶子节点开始的位置是int(i/2),因此第一个令其保持性质的结点下标为int((i-1)/2)。接着是int((i-1)/2-1)一直到0为止。下图表示了构建堆的详细过程:
图中有9个结点,int(9/2)= 4, 从4-1=3开始(依次是4 3 2 1 0)。注意是从后往前,为何不是从前往后,显然如果是上图中,从0开始,是6和3交换,我们知道在最大堆中根是最大的,可是从前往后的话,最大值7在无出头之日。
参考程序:
void BUILD_MAX_HEAP(int *A, int array_size, int heap_size){ int i; for (i=array_size/2-1; i>=0; i--) { MAX_HEAPIFY(A, heap_size, i); }}
四 堆排序
最大堆把最大值排到了首个位置A[0],这是如果把最大值和最后一个值A[heap_size-1]换过来,再使A[0]保持堆的性质,再使heap_size自建。重复以上过程,就是个非递减排序。下图是一个事例过程:
参考程序:
void HEAP_SORT(int *A, int array_size, int heap_size){ int tmp; BUILD_MAX_HEAP(A, array_size, heap_size); while(heap_size > 1) { tmp = A[0]; A[0] = A[heap_size-1]; A[heap_size] = tmp; heap_size--; MAX_HEAPIFY(A, heap_size, 0); }}
五 堆操作
1.HEAP_MAXIMUM(A) 找出最大的元素
int HEAP_MAXIMUM(int *A){ return A[0];}
2.int HEAP_EXTRACT_MAX(int *A, int heap_size) 找出堆中最大元素,并删除,保持堆
int HEAP_EXTRACT_MAX(int *A, int heap_size){ int max; max = A[0]; A[0] = A[heap_size-1]; heap_size--; MAX_HEAPIFY(A, heap_size, 0); return max;}
3. void HEAP_INCREASE_KEY(int *A, int heap_size, int i, int key) 第i个位置出若key比原来大,就改成key,保持堆
void HEAP_INCREASE_KEY(int *A, int heap_size, int i, int key){ int tmp; if(A[i] > key) { printf("The key is smaller than A[i]"); } else { A[i] = key; while(i>=1 && A[(i-1)/2] < A[i]) { tmp = A[i]; A[i] = A[(i-1)/2]; A[(i-1)/2] = tmp; i = (i-1)/2; MAX_HEAPIFY(A, heap_size, i); } }}
4.void MAX_HEAP_INSERT(int *A, int array_size, int heap_size, int key) 堆中插入元素
void MAX_HEAP_INSERT(int *A, int array_size, int heap_size, int key){ array_size++; heap_size++; A[heap_size] = -32768; HEAP_INCREASE_KEY(A, heap_size, heap_size-1, key);}
- 堆及堆排序
- 堆/堆排序特点
- 【二叉堆、堆排序】
- 二叉堆 & 堆排序
- 二叉堆 & 堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆和堆排序
- 堆排序(最大堆)
- 堆和堆排序
- 堆和堆排序
- 堆及堆排序
- 堆和堆排序
- 堆与堆排序
- android笔记(1)--环境的搭建
- java中的super()
- mysql过滤数据(二)
- Github上600多个iOS开源项目分类及介绍
- C#禁用USB接口
- 堆排序
- 用java写的Notepad简单实现版
- 1到100,放在长度99的数组里,有一个没有在里面,编程找出那个数
- XStream使用方法
- OCP-1Z0-052-V8.02-5题
- <<深入浅出MFC>>笔记1——Win32基本程序观念
- 分享给力咨询品牌建设里程碑之心得总结
- nginx+php产生大量TIME_WAIT
- Myeclipse10.0 下findbugs,svn的安装