最大堆的插入 删除 初始化 堆排序

news/2024/5/19 6:47:30 标签: 堆排序, c++, heap, 异常, 二叉树
//
//  main.cpp
//  Heap
//
//  Created by xin wang on 5/5/15.
//  Copyright (c) 2015 xin wang. All rights reserved.
//

#include <iostream>
class OutOfBound{
public:
     OutOfBound(){
        std::cout<<"越界"<<std::endl;
    }
};

class NoMen{
public:
    NoMen(){
        std::cout<<"No Men"<<std::endl;
    }
};

template <class T>
class MaxHeap{
public:
    MaxHeap(int MaxHeapSize=10);
    ~MaxHeap(){
        delete []heap;
    }
    int Size()const{
        return CurrentSize;
    }
    T Max(){
        if (CurrentSize==0) {
            throw OutOfBound();
        }
        return heap[1];

    }
    MaxHeap<T>& Insert(const T& x);
    MaxHeap<T>& DeleteMax(T& x);
    void Initialize(T a[],int size,int ArraySize);
    void Deactivate(){
        heap=0;
    }
private:
    int CurrentSize;
    int MaxSize;
    T *heap;
};

template <class T>
MaxHeap<T>::MaxHeap(int MaxHeapSize){
    MaxSize = MaxHeapSize;
    heap = new T[MaxSize+1];
    CurrentSize=0;
}

//最大堆的插入
template <class T>
MaxHeap<T>& MaxHeap<T>::Insert(const T& x){
    //把x插入到最大堆中
    if (CurrentSize==MaxSize) {
        throw NoMen();//没有足够的空间
    }
    int i= ++CurrentSize;
    while (i != 1&& x>heap[i/2]) {
        heap[i] = heap[i/2];//将元素下移
        i/=2;//移向父节点
    }
    heap[i]=x;
    return *this;
}

//最大堆的删除
template <class T>
MaxHeap<T>& MaxHeap<T>::DeleteMax(T& x){
    //将最大元素放入x,并从堆中删除最大元素
    if (CurrentSize==0) {//越界
        throw OutOfBound();
    }
    
    x=heap[1];//将最大的元素放入x
    T y = heap[CurrentSize--];
    int i=1,ci=2;
    while (ci<=CurrentSize) {
        if (ci<CurrentSize && heap[ci]<heap[ci+1]) {
            ci++;//找到较大的孩子的位置
        }
        if (y>heap[ci]) {//能把y放入heap[i]
            break;
            
        }
        heap[i]=heap[ci];//将孩子上移
        i=ci;//下移一层
        ci*=2;
    }
    heap[i]=y;
    return *this;
    
    
}

template <class T>
void MaxHeap<T>::Initialize(T a[], int size, int ArraySize){
    delete []heap;
    heap=a;
    CurrentSize = size;
    MaxSize = ArraySize;
    
    for (int i= CurrentSize/2; i>=1; i--) {
        T y = heap[i];//子树的根
        
        int c = 2*i;
        while (c<=CurrentSize) {
            if (c <CurrentSize && heap[c]<heap[c+1]){
                c++;
            }
            if (y>=heap[c]) {
                break;
            }
            heap[c/2]=heap[c];//将孩子上移
            c*=2;//下移一层
        }
        heap[c/2]=y;

    }

}

template <class T>
void HeapSort(T a[],int n){
    //对a[1:n]进行排序
    MaxHeap<T> H(1);
    H.Initialize(a,n,n);
//    for (int ii=1; ii<=n; ii++) {
//        std::cout<<a[ii]<<" ";
//    }
    
    T x;
    std::cout<<"output:"<<std::endl;
    for (int i=n-1; i>=1; i--) {
        H.DeleteMax(x);
        std::cout<<x<<" ";
        a[i+1] =x;
    }
    H.Deactivate();//析构
}

int main(int argc, const char * argv[]) {
    // insert code here...,
    int array[20];
    std::cout<<"please enter an array,0 is end"<<std::endl;
    int i=0;
    int b=1;
    //初始化数组,输入0结束
    while(std::cin>>i){
        if (i==0) {
            break;
        }
        array[b]=i;
        b++;
        
    }
    
    HeapSort(array, b);
    return 0;
}


http://www.niftyadmin.cn/n/795037.html

相关文章

组合优于继承

文章目录一个类中分开变与不变的部分继承组合抽象人类行为 接口实现相应的Behavior不同的人用法&#xff1a;优点总结在平时开发中&#xff0c;有时会遇到这样一种情形&#xff1a;有一个类&#xff0c;他有很多行为&#xff0c;有的行为是固定的&#xff0c;有的行为又是可变的…

继承优于标签

在开发中&#xff0c;我们经常会遇到一种情形&#xff1a;有的类&#xff0c;根据不同的属性&#xff08;Tag&#xff09;&#xff0c;可以表现出不同的行为。比如&#xff1a;我们有一个图形类Figure,它可以表现圆形Circle、矩形Rectangle。你会怎么设计呢&#xff1f; 标签 …

C#多线程(-) -- 概念梳理

其中委托的BeginInvoke方法以及回调函数最为常用。 而 I/O线程可能容易遭到大家的忽略&#xff0c;其实在开发多线程系统&#xff0c;更应该多留意I/O线程的操作。特别是在ASP.NET开发当中&#xff0c;可能更多人只会留意在客户端使用Ajax或者在服务器端使用UpdatePanel。其实…

C#多线程(二) -- ThreadStart

ThreadStart 方式实现多线程 先以一个例子体现一下多线程带来的好处&#xff0c;首先在Message类中建立一个方法ShowMessage()&#xff0c;里面显示了当前运行线程的Id&#xff0c;并使用Thread.Sleep&#xff08;int ) 方法模拟部分工作。在main()中通过ThreadStart委托绑定M…

css中的margin

margin: 20px 30px 40px 50px;的意思是距离上部20px&#xff0c;距离右边30px&#xff0c;距离下边40px,距离左边50px。 #main{width:600px;margin:0 auto;}设置width可以避免控件的大小随着容器的大小的变化而改变。当浏览器窗口较小的时候&#xff0c;会出现滚动条。然后设置…

C多线程(三) -- CLR线程池的工作者线程

1. 关于CLR线程池 使用ThreadStart与ParameterizedThreadStart建立新线程非常简单&#xff0c;但通过此方法建立的线程难于管理&#xff0c;若建立过多的线程反而会影响系统的性能 所以&#xff0c;.NET引入CLR线程池这个概念。CLR线程池并不会在CLR初始化的时候立刻建立线程…

.NET Framework 入门

官方中文文档链接 官方中文文档 .NET Framework 入门 简单理解下&#xff1a; .NET Framework 是管理面向 .NET Framework 的应用程序的运行时执行环境。 它包括&#xff1a; 公共语言运行时&#xff08;提供了内存管理和其他系统服务&#xff09;.NET Framework 类库&#x…

css中的max-width

#mian{max-width:600px;margin:0 auto;}设置max-width主要是为了应对浏览器处理小窗口的时候的情况。这在移动端非常有用。当设置max-width的时候&#xff0c;浏览器会根据浏览器窗口的大小而自动调整空间的大小&#xff0c;而设置width的时候&#xff0c;如果浏览器的窗口变小…