最大堆及堆排序的实现

 堆数据结构用于排序算法中,空间复杂度O(1),时间复杂度O(NlogN),但是在实践中还是不如快速排序(好像快速排序可以更好的利用硬件特性)。堆的意义就在于:最快的找到最大/最小值,在堆结构中插入一个值重新构造堆结构,取走最大/最下值后重新构造堆结构 其时间复杂度为O(logN),而其他方法最少为O(N).堆实践中用途不在于排序,其主要用在调度算法中,比如优先级调度,每次取优先级最高的,时间驱动,取时间最小/等待最长的 等等 ,分为最大堆/最小堆。

这里讨论最大堆,最小堆与最大堆类似。

void MaxHeapify(int i):移动一个指定的元素使其符合最大堆。

void BuildMaxHeap():对已知的数组元素构造最大堆。通过调用MaxHeapify来实现。

T Maximum():返回最大值。

T ExtractMaximum():提取最大值,堆中元素少一,提取后还是一个最大堆。

void IncreaseKey(int i, T key):对指定位置的元素进行增大操作,操作后仍为最大堆。

void HeapInsert(T key):在最大堆中执行插入操作,先在数组最后边添加一个无穷小元素,然后调用IncreaseKey来实现。

void HeapSort():对最大堆进行排序,注意,排序后的数组不再是最大堆。

下面是具体的实现:

template  < typename T >
class  MaxHeap
{
public:
    MaxHeap(
int max_size, int cur_size, T data[]) : cur_size_(cur_size), max_size_(max_size)
    
{
        
if (max_size_ < cur_size_)
            
throw logic_error("Maximum size must no more less then the current size!");

        heap_ 
= new T[max_size_ + 1];
        copy(data, data 
+ cur_size_, heap_ + 1);
    }

    
~MaxHeap() 
    
{
        delete []heap_;
    }

    
void MaxHeapify(int i)
    
{
        
int l = left(i);
        
int r = right(i);
        
int largest = i;

        
if (l <= cur_size_ && heap_[l] > heap_[largest])
            largest 
= l;

        
if (r <= cur_size_ && heap_[r] > heap_[largest])
            largest 
= r;

        
if (largest != i)
        
{
            swap(heap_[largest], heap_[i]);
            MaxHeapify(largest);
        }

    }

    
void BuildMaxHeap()
    
{
        
for (int i = cur_size_ / 2; i >= 1; i--)
        
{
            MaxHeapify(i);
        }

    }

    T Maximum()
    
{
        
return heap_[1];
    }

    T ExtractMaximum()
    
{
        
if (cur_size_ <= 1)
            
throw logic_error("No element in max heap!");

        T max 
= heap_[1];
        heap_[
1= heap_[cur_size_];
        cur_size_
--;
        MaxHeapify(
1);

        
return max;
    }

    
void IncreaseKey(int i, T key)
    
{
        
if (key < heap_[i])
            
throw logic_error("the new key is smaller than current key!");

        heap_[i] 
= key;
        
while (i > 1 && heap_[parent(i)] < heap_[i])
        
{
            swap(heap_[parent(i)], heap_[i]);
            i 
= parent(i);
        }

    }

    
void HeapInsert(T key)
    
{
        
if (max_size_ <= cur_size_)
            
throw logic_error("The heap is out of size, can't insert!");

        cur_size_
++;
        heap_[cur_size_] 
= T(-0xFFFF);
        IncreaseKey(cur_size_, key);
    }
    
    
void HeapSort()
    
{
        
int tmp_size = cur_size_;
        
for (int i = tmp_size; i > 1; i--)
        
{
            swap(heap_[
1], heap_[i]); 
            cur_size_
--;
            MaxHeapify(
1);
        }

        
// restore the size
        cur_size_ = tmp_size;
    }

    ostream
& print(ostream& out
    
{
        copy(heap_ 
+ 1, heap_ + cur_size_ + 1, ostream_iterator<T>(out" ")); 
        
return out
    }
    

private:
    
int parent(int i) return i / 2; }
    
int left(int i)   return i * 2; }
    
int right(int i)  return i * 2 + 1; }

private:
    
int cur_size_;
    
int max_size_;
    T
* heap_;
}
;

template 
< typename T >
ostream
&   operator   << (ostream &   out , MaxHeap < T >&  mh)
{
    
return mh.print(out);
}

下面是测试代码:

int  main()
{
    
int data[10= {4132169101487};
    
int count = sizeof(data) / sizeof(int);

    MaxHeap
<int> mh(2 * count, count, data);
    cout 
<< "Before build: " << mh << endl;

    mh.BuildMaxHeap();
    cout 
<< "After build: " << mh << endl;

    mh.HeapSort();
    cout 
<< "After sort: " << mh << endl;

    
return getchar();
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值