1. Sift-up
假定对于某个i>1,H[i]变成了键值大于它父节点键值的元素,这样就违反了堆的特性。我们需要使用Sift-up运算把新的数据项移到在二叉树中适合它的位置上。
Sift-up的运算沿着从H[i]到根节点的唯一一条路径,把H[i]移到适合它的位置上。在沿着路径的每一步上,都将H[i]键值和它父节点的键值H[⌊i/2⌋]相比较。
过程 Sift-up
输入 数组H[1...n]和位于1和n之间的索引i
输出 上移H[i](如果需要),以使它不大于父节点
算法描述
done ← false
if i = 1 then exit {节点i为根}
repeat
if key(H[i]) > key(H[⌊i/2⌋]) then 互换H[i]和H[⌊i/2⌋]
else done ← true
i ← ⌊i/2⌋
until i = 1 or done
注意这里算法描述的数组的索引都是1...n,而不是大家习惯的0...n-1。
// heap[0]用来存储数组中堆数据的长度,堆数据heap[1]...heap[heapLength]
// 所以数组的实际长度是heapLength+1,我们只对从数组索引为1开始的heapLength个数据进行操作
void siftUp(int* heap, int index)
{
int heapLength = heap[0];
if (index < 1 || index > heapLength)
return;
bool done = false;
while(!done && index > 1)
{
if (heap[index] > heap[index / 2])
{
int temp = heap[index];
heap[index] = heap[index / 2];
heap[index / 2] = temp;
}
else
{
done = true;
}
index /= 2;
}
}
2. Sift-down
假定对于i ≤ ⌊n/2⌋,存储在H[i]中元素的键值变成小于H[2i]和H[2i+1]中的最大值(如果2i+1存在的话),这样也违反了堆的特性。Sift-down运算使H[i]“渗”到二叉树中适合它的位置上,沿着这条路径的每一步,都把H[i]的键值和存储在它子节点(如果存在)中的两个键值里最大的那个相比较。
过程 Sift-down
输入 数组H[1...n]和位于1和n之间的索引i
输出 下移H[i](如果需要),以使它不小于子节点
算法描述
done ← false
if 2i > n then exit {节点i是叶子}
repeat
i ← 2i
if i + 1 ≤ n and key(H[i+1]) > key(H[i]) then i ← i + 1
if key(H[⌊i/2⌋]) < key(H[i]) then 互换H[i]和H[⌊i/2⌋]
else done ← true
end if
until 2i > n or done
注意这里算法描述的数组的索引也都是1...n,而不是大家习惯的0...n-1。
// heap[0]用来存储数组中堆数据的长度,堆数据heap[1]...heap[heapLength]
// 所以数组的实际长度是heapLength+1,我们只对从数组索引为1开始的heapLength个数据进行操作
void siftDown(int* heap, int index)
{
int heapLength = heap[0];
if (index < 1 || index * 2 > heapLength)
return;
bool done = false;
while(!done && index * 2 <= heapLength)
{
index *= 2;
if (index + 1 <= heapLength && heap[index + 1] > heap[index])
index += 1;
if (heap[index] > heap[index / 2])
{
int temp = heap[index];
heap[index] = heap[index / 2];
heap[index / 2] = temp;
}
else
{
done = true;
}
}
}
我使用的数组是这样定义的:
const int HEAP_LENGH = 10;
int heap[HEAP_LENGH + 1] = { HEAP_LENGH, 20, 3, 9, 10, 11, 4, 5, 3, 7, 5 };
// 这个数组用 siftDown(heap, 2) 方法可以看到效果
更多内容请参考:
算法 之 堆 - 简介
分享到:
相关推荐
配准算法程序,包含SIFT,SAR-SIFT等
pso-sift源码,底层代码编写,有较完整的步骤和每一步的说明,对于pso-sift初学者特别有帮助
为了学习python以及配准,特地设置的一个程序,用以实现sift算法以及sar-sift算法
关于PCASIFT的源码,比较简单,适合初入门的新手。
PCA-SIFT matlab,对学习局部区域算子的人会有所帮助。
2016年提出的Uniform SAR-SIFT算法,作SAR图像方面的可以看看。
这个代码是pca-sift的MATLAB代码,是原作者自己编写的,广泛适用于初学者。
CVPR2015年论文代码! DSP-sift算法,各位我自己跑了一圈,用的是opencv2.0
描述了sift、pca-sift、surf,并进行比较
autopano-sift-C is a C port of the C# software autopano-sift. It is somewhat faster and doesn t require a C# runtime- Installing the mono C# runtime on OS X has proved to be problematic on some ...
针对传统点云配准方法在处理大型点云模型时存在计算量大、效率低和移动扫描配准实时性较差等问题,提出基于卷积神经网络结合改进Harris-SIFT(Scale Invariant Feature Transform)的点云配准方法。首先改进Harris-SIFT...
mod_lowe 的pca-sift c语言实现,可以参考如何提取特征点和匹配的实现
SIFT\PCA-SIFT\SURF论文文章和对应的源代码
A Comparison of SIFT, PCA-SIFT and SURF.ppt
sar-sift源码,底层代码编写,有较完整的步骤和每一步的说明,对于sar-sift初学者特别有帮助
。。。
。。。
Relief计算分类权重,借鉴了主成分分析算法(PCA),结合PCA的尺度不变特征变换(SIFT)算法。
PCA-SIFT 算法的代码,vsual c++ 实现,希望对大家有帮助!加油!
SAR SIFT图像配准算法。yishiliuhuasheng/sar_sift