算法导论第六章伪码转C++ ___堆排序
2014-10-08 20:10
330 查看
heap.h:
#include<iostream>
using namespace std;
class Fheap
{
public:
};
int Parent(int i){return (i-1)/2;} //从0索引,i/2变成(i-1)/2
int LeftChild(int i){return 2*i + 1;} //从0索引, 2*i 变成2*i + 1
int RightChild(int i){return 2*i + 2;}//从0索引 2*i + 1变成2*i + 2
void Fswap(int& a, int& b)
{
int c = a;
a = b;
b = c;
}
//维护堆的函数,默认条件在P85,默认根节点为left[i]和right[i]的二叉树
//都是最大堆,所以建堆需要那样从最后一个父节点倒着依次
//这种条件导致要维护的节点小于其父节点,否则应该维护其父节点
//当满足这种条件只是节点大于其父节点,则应该再维护其父节点,实际建堆就是这么干的
void Max_Heapify(int A[], int i, int n)
{
//第二个参数i传来时,减1,即要维护的在A[i]不是第几个数
// cout <<"A[" << i << "] :" << A[i] << endl;
int l = LeftChild(i) ; //从A[0}开始的数组时与课本上从1开始规律不同
int r = RightChild(i);
//这里建堆时存在越界问题,比如10个数从10/2=5,右子11,A[11]越界
//所以要求,l,r小于n,用从1开始的数组,是小于等于,可防止越界
// cout << "l,r " << l << "," << r << endl;
int largest;
if ( (l < n) &&(A[l]> A[i]))
largest = l;
else largest = i;
if ((r < n) && (A[r] > A[largest]))
largest = r;
// cout << "largest,i :" << largest << " " << i << endl;
if (largest != i)
{
Fswap(A[i],A[largest]);
Max_Heapify(A,largest,n);
//第二个参数不要减1,因为largest为i,l,r的值,这些都经过处理了
}
}
void Build_Max_heap(int A[], int n)
{
int Aheapsize = n;
for (int i = n/2; i >= 1; i--)
Max_Heapify(A,i-1,Aheapsize);
//这是常规数组的对应的i-1,如果要垫个0,则不用
}
void Heap_Sort(int A[], int n)
{
int Asize = n;
Build_Max_heap(A,n);
for (int i = n - 1; i >= 1; i-- )//异
{
Fswap(A[0],A[i]); //A[0]异
Asize = Asize - 1;
Max_Heapify(A,0,Asize);//从A[0]开始的第二个参数为A[0]
}
}
int Heap_Maximum(int A[])
{
return A[0]; //异
}
int Heap_Extract_Max(int A[], int n)
{
if (n < 1)
{
cout << "error! heap underflow" << endl;
return -9999; //这是错误时返回一个很小的数,应该有更好的处理方式
}
int max = A[0];
A[0] = A[n - 1];//异
n = n - 1;
Max_Heapify(A,0,10);//0异
return max;
}
void Heap_Increase_Key(int A[],int i, int key, int n)
{
//第二个参数注意下,是否是A[i]
if(key < A[i])
cout << "error ! new key is smaller than current key" << endl;
A[i] = key;
//试试这里用维护堆行不
// Max_Heapify(A,i,n);
//这里用不行,看看heapify的原理,是从某个往树下找,
//所以建堆时才从中间依次往树上维护(不是这样调一次),这里如果要heapify也可那样用
//但是相当于重新建堆(或者直接调用新建堆),而原来只是一个值变了,重新建效率不高
// Build_Max_heap(A,n);//这样可以
while( (i > 0) && (A[Parent(i)] < A[i]))
//因为此函数是增值,所以不用向树下检查
{
Fswap(A[i],A[Parent(i)]);
//从1索引的一些规律,从0开始不一定好使,这个需时刻记住
i = Parent(i);
}
}
void Max_Heap_Insert(int A[],int key, int n)
{
n = n + 1;
A
= -9999;
Heap_Increase_Key(A,n-1,key,n);//参数n-1
}
main.cpp
#include<iostream>
#include"heap.h"
using namespace std;
void ShowHeap(int A[],int n)
{
cout << "heap is :" << endl;
for (int i = 0; i < 10 ; i++)
cout << A[i] << " ";
cout << endl;
}
int main()
{ int A[10] = {16,4,10,14,7,9,3,2,8,1};
Build_Max_heap(A,10);
ShowHeap(A,10);
Heap_Increase_Key(A,8,15,10); //8是A[8]
ShowHeap(A,10);
Max_Heap_Insert(A,13,10);//把元素13插入堆
ShowHeap(A,10);
return 0;
}
#include<iostream>
using namespace std;
class Fheap
{
public:
};
int Parent(int i){return (i-1)/2;} //从0索引,i/2变成(i-1)/2
int LeftChild(int i){return 2*i + 1;} //从0索引, 2*i 变成2*i + 1
int RightChild(int i){return 2*i + 2;}//从0索引 2*i + 1变成2*i + 2
void Fswap(int& a, int& b)
{
int c = a;
a = b;
b = c;
}
//维护堆的函数,默认条件在P85,默认根节点为left[i]和right[i]的二叉树
//都是最大堆,所以建堆需要那样从最后一个父节点倒着依次
//这种条件导致要维护的节点小于其父节点,否则应该维护其父节点
//当满足这种条件只是节点大于其父节点,则应该再维护其父节点,实际建堆就是这么干的
void Max_Heapify(int A[], int i, int n)
{
//第二个参数i传来时,减1,即要维护的在A[i]不是第几个数
// cout <<"A[" << i << "] :" << A[i] << endl;
int l = LeftChild(i) ; //从A[0}开始的数组时与课本上从1开始规律不同
int r = RightChild(i);
//这里建堆时存在越界问题,比如10个数从10/2=5,右子11,A[11]越界
//所以要求,l,r小于n,用从1开始的数组,是小于等于,可防止越界
// cout << "l,r " << l << "," << r << endl;
int largest;
if ( (l < n) &&(A[l]> A[i]))
largest = l;
else largest = i;
if ((r < n) && (A[r] > A[largest]))
largest = r;
// cout << "largest,i :" << largest << " " << i << endl;
if (largest != i)
{
Fswap(A[i],A[largest]);
Max_Heapify(A,largest,n);
//第二个参数不要减1,因为largest为i,l,r的值,这些都经过处理了
}
}
void Build_Max_heap(int A[], int n)
{
int Aheapsize = n;
for (int i = n/2; i >= 1; i--)
Max_Heapify(A,i-1,Aheapsize);
//这是常规数组的对应的i-1,如果要垫个0,则不用
}
void Heap_Sort(int A[], int n)
{
int Asize = n;
Build_Max_heap(A,n);
for (int i = n - 1; i >= 1; i-- )//异
{
Fswap(A[0],A[i]); //A[0]异
Asize = Asize - 1;
Max_Heapify(A,0,Asize);//从A[0]开始的第二个参数为A[0]
}
}
int Heap_Maximum(int A[])
{
return A[0]; //异
}
int Heap_Extract_Max(int A[], int n)
{
if (n < 1)
{
cout << "error! heap underflow" << endl;
return -9999; //这是错误时返回一个很小的数,应该有更好的处理方式
}
int max = A[0];
A[0] = A[n - 1];//异
n = n - 1;
Max_Heapify(A,0,10);//0异
return max;
}
void Heap_Increase_Key(int A[],int i, int key, int n)
{
//第二个参数注意下,是否是A[i]
if(key < A[i])
cout << "error ! new key is smaller than current key" << endl;
A[i] = key;
//试试这里用维护堆行不
// Max_Heapify(A,i,n);
//这里用不行,看看heapify的原理,是从某个往树下找,
//所以建堆时才从中间依次往树上维护(不是这样调一次),这里如果要heapify也可那样用
//但是相当于重新建堆(或者直接调用新建堆),而原来只是一个值变了,重新建效率不高
// Build_Max_heap(A,n);//这样可以
while( (i > 0) && (A[Parent(i)] < A[i]))
//因为此函数是增值,所以不用向树下检查
{
Fswap(A[i],A[Parent(i)]);
//从1索引的一些规律,从0开始不一定好使,这个需时刻记住
i = Parent(i);
}
}
void Max_Heap_Insert(int A[],int key, int n)
{
n = n + 1;
A
= -9999;
Heap_Increase_Key(A,n-1,key,n);//参数n-1
}
main.cpp
#include<iostream>
#include"heap.h"
using namespace std;
void ShowHeap(int A[],int n)
{
cout << "heap is :" << endl;
for (int i = 0; i < 10 ; i++)
cout << A[i] << " ";
cout << endl;
}
int main()
{ int A[10] = {16,4,10,14,7,9,3,2,8,1};
Build_Max_heap(A,10);
ShowHeap(A,10);
Heap_Increase_Key(A,8,15,10); //8是A[8]
ShowHeap(A,10);
Max_Heap_Insert(A,13,10);//把元素13插入堆
ShowHeap(A,10);
return 0;
}
相关文章推荐
- 算法导论-第六章-堆排序:基于最大堆的排序C++实现
- 算法导论第六章 堆排序C++源码(附图)
- 算法导论第六章 堆排序C++源码(附图)
- 算法导论(第三版)第六章 堆排序的全部实现(堆排序,优先队列)
- 《算法导论》第六章“堆排序”习题解答
- 算法导论第八章伪码转C++ __桶排序
- 《算法导论》第六章----堆排序
- 《算法导论》第六章----堆排序练习(证明)(完整版)
- 算法导论 第六章 堆排序
- 学习《算法导论》第六章 堆排序 总结
- 算法导论第八章伪码转C++_计数排序
- 算法导论学习笔记-第六章-堆排序
- 算法导论第六章 堆排序
- 算法导论第六章总结:堆排序
- 算法导论 第六章:堆排序
- 算法导论第七章伪码转C++__快速排序
- 算法导论第六章 堆排序
- 《算法导论》学习笔记--第六章 堆排序
- 算法导论 第六章优先队列C++实现
- 算法导论第六章 堆排序