目录
减治法的基本思路
- 将原问题的解分解成若干个子问题,且原问题的解与子问题的解之间存在某种确定关系
- 如果原问题的规模为n,则子问题的规模通常为n/2或n-1
- 与分治法不同的是,减治法不需要对分解的子问题分别求解,也不需对子问题的解进行合并
堆排序基本步骤
(注:进行建初堆时,是从最后一个分支节点开始从右往左、从下往上的调整;进行排序时则是从根结点开始从上往下从左往右进行)
代码部分(Java)
调整堆
void SiftHeap(int r[],int k,int n)
{
int i,j,temp;
i=k; j=2*i+1; //i为当前要筛选的根结点,j为i的左孩子
while(j<n) //筛选还未进行到叶子
{
if(j<n-1 && r[j]<r[j+1]) j++; //比较i的左右孩子,j为左右孩子中较大者的下标 (j<n-1说明i有右孩子)
if(r[i]>r[j]) break; // r[i]>r[j]说明已经是个大根堆,则退出while循环
else //否则,将其调整成大根堆
{
temp=r[j]; r[j]=r[i]; r[i]=temp;
i=j;j=2*i+1; //被筛的结点位于原来结点j的位置
}
}
}
初建堆
void HeapSort(int r[],int n)
{
int i,temp;
for(i=(n-1)/2;i>=0;i--) //找到二叉树的最后一个分支
SiftHeap(r,i,n); //建初堆将其变成一个大根堆
for(i=1;i<=n-1;i++)
{
temp=r[0]; r[0]=r[n-i]; r[n-i]=temp; //将大根堆的堆顶元素移走—>找到序列的第i大元素
SiftHeap(r,0,n-i); //调整根结点,进行n-i次操作
}
}