您的位置:首页 > 编程语言 > C语言/C++

算法导论第六章伪码转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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: