算法导论第六章伪码转C++ ___堆排序

来源:互联网 发布:淘宝有没有卖透视眼镜 编辑:程序博客网 时间:2024/06/06 02:50

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[n] = -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;
}


0 0