您的位置:首页 > 其它

最大堆、最小堆、堆排序

2015-07-06 11:28 465 查看
最(大)小堆的性质

(1)是一颗完全二叉树,遵循完全二叉树的所有性质。

(2)父节点的键值(大于)小于等于子节点的键值

(3)在堆排序中我们通常用的是最大堆,最小堆通常用在优先队列中(尚未找到恰当的例子)。

堆排序:

数组:a[10]={16,14,10,8,7,9,3,2,4,1}可以利用建堆的方式对其进行排序。因为堆是一颗完全二叉树,根据完全二叉树的性质可以得知:对数组进行建堆之后,给定任意下标节点其父节点下标PARENT(i)=i/2      (取下整数)。左孩子下标为LEFT(i)=2*i 。右孩子下标为RIGHT(i)=2*i+1.如下图所示

堆排序代码见如下:

[cpp]
view plaincopy

#include<iostream>  
using namespace std;  
//获取父节点  
int Parent(int i)  
{  
    return i/2;  
}  
//获取左孩子  
int Left(int i)  
{  
    return 2*i;  
}  
//获取右孩子  
int Right(int i)  
{  
    return 2*i+1;  
}  
//从i节点开始生成最大堆  
void MaxHeap(int *a,int i,int length)  
{  
    int L,R;  
    L=Left(i);  
    R=Right(i);  
    int largest;  
    if(L<=length&&a[L-1]>a[i-1])  
    {  
        largest=L;  
    }  
    else  
        largest=i;  
    if(R<=length&&a[R-1]>a[largest-1])  
    {  
        largest=R;  
    }  
    if(largest!=i)  
    {  
        int temp;  
        temp=a[i-1];  
        a[i-1]=a[largest-1];  
        a[largest-1]=temp;  
        MaxHeap(a,largest,length);  
    }  
}  
//将整个树生成最大堆  
void Build_Max_Heap(int *a,int length)  
{  
    //从length/2开始是因为length/2节点以下的都是叶子节点  
    for(int i=length/2;i>=1;i--)  
    {  
        MaxHeap(a,i,length);  
    }  
}  
//堆排序  
void HeapSort(int *a,int length)  
{  
    Build_Max_Heap(a,length);  
    int number=length;  
    for(int i=length;i>0;i--)  
    {  
        int temp;  
        temp=a[i-1];  
        a[i-1]=a[0];  
        a[0]=temp;  
        length-=1;  
        MaxHeap(a,1,length);  
    }  
}  
int main()  
{  
    int a[10]={4,1,3,2,16,9,10,14,8,7};  
    HeapSort(a,10);  
    for(int i=0;i<10;i++)  
    {  
        cout<<a[i]<<" ";  
    }  
    cout<<endl;  
}  

 利用最小堆对数组进行排序的实现代码如下:

[cpp]
view plaincopy

#include<iostream>  
using namespace std;  
template<typename Type>class MinHeap  
{  
private:  
    Type *heap;  
    static const int defaultsize=1000;  
    int MaxSize;  
    int currentsize;  
public:  
    MinHeap<Type>(int size)  
    {  
        currentsize=0;  
        Maxsize=defaultsize>size?size:defaultsize;  
    }  
    MinHeap<Type>(Type a[],int n);  
    bool Insert(Type n);  
    bool IsFull()  
    {  
        return currentsize==MaxSize;  
    }  
    bool IsEmpty()  
    {  
        return currentsize==0;  
    }  
    bool Delete(Type n);  
    void Adjust(int start,int n);  
    void Print();  
    void Sorte();  
};  
template<typename Type> MinHeap<Type>::MinHeap(Type a[], int n)  
{  
      
    MaxSize=defaultsize>n?n:defaultsize;  
    currentsize=MaxSize;  
    heap=new Type[MaxSize];  
    for(int i=0;i<MaxSize;i++)  
    {  
        heap[i]=a[i];  
    }  
    int temp=(MaxSize-2)/2;  
    for(int i=temp;i>=0;i--)  
    {  
        Adjust(i,currentsize);  
    }  
}  
template<typename Type>bool MinHeap<Type>::Insert(Type n)  
{  
    if(currentsize==MaxSize)  
    {  
        cout<<"the heap is full!"<<endl;  
    }  
    heap[currentsize]=n;  
    int j=currentsize;  
    while(j>0)  
    {  
        int P=j/2-1;  
        if(heap[P]<heap[j])  
            break;  
        int temp;  
        temp=heap[P];  
        heap[P]=heap[currentsize];  
        heap[currentsize]=temp;  
        j=P;  
    }  
    currentsize++;  
    return 1;  
}  
template<typename Type>bool MinHeap<Type>::Delete(Type n)  
{  
    if(currentsize==0)  
    {  
        cout<<"this heap is empty!"<<endl;  
    }  
    bool flag=0;  
    for(int i=0;i<currentsize;i++)  
    {  
        if(heap[i]==n)  
        {  
            flag=1;  
            heap[i]=heap[currentsize-1];  
            Adjust(i,currentsize-2);  
            currentsize--;  
            i=0;  
        }  
        if(i==currentsize-1&&flag==0)  
        {  
            cout<<"there is no this element!"<<endl;  
        }  
    }  
    return 1;  
}  
template<typename Type>void MinHeap<Type>::Print()  
{  
    for(int i=0;i<currentsize;i++)  
    {  
        cout<<heap[i]<<"   ";  
    }  
    cout<<endl;  
}  
template<typename Type>void MinHeap<Type>::Adjust(int start, int n)  
{  
    int L,R,min;  
    L=start*2+1;  
    R=L+1;  
      
    if(heap[start]>heap[L]&&L<n)  
    {  
        min=L;  
    }  
    else  
        min=start;  
    if(heap[min]>heap[R]&&R<n)  
    {  
        min=R;  
    }  
    if(start!=min)  
    {  
        int temp;  
        temp=heap[start];  
        heap[start]=heap[min];  
        heap[min]=temp;  
        Adjust(min,n);  
    }  
}  
template<typename Type>void MinHeap<Type>::Sorte()  
{  
    int num=currentsize;  
    for(int i=currentsize-1;i>0;i--)  
    {  
        int temp;  
        temp=heap[i];  
        heap[i]=heap[0];  
        heap[0]=temp;  
        num-=1;  
        Adjust(0,num);  
    }  
}  
int main()  
{  
    int init[30]={17,6,22,29,14,0,21,13,27,18,2,28,8  
        ,26,3,12,20,4,9,23,15,1,11,5,19,24,16,7,10,25};  
    MinHeap<int> heape(init,30);  
    heape.Print();  
    cout<<endl<<endl<<endl;  
  
    heape.Insert(20);  
    heape.Print();  
    cout<<endl<<endl<<endl;  
  
    heape.Delete(20);  
    heape.Sorte();  
    heape.Print();  
    cout<<endl<<endl<<endl;  
  
    return 0;  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树 堆排序 算法