#include<iostream>
//#include <vector>
#include <algorithm>
#include"MinHeap.h"
using namespace std;
#define max 100
class JobNode{
friend void Greedy(JobNode *,int,int);
friend void main(void);
public:
operator int() const {return time;}
//private:
int ID,time;
};
class MachineNode{
friend void Greedy(JobNode *,int,int);
public:
operator int() const {return avail;}
//private:
int ID,avail;
};
void Greedy(JobNode *a,int n,int m)
{
if(n<=m){
cout<<"为每个作业分配一台机器。"<<endl;
return;
}
sort(a[0].time,a[n].time,n);
MinHeap<int,MachineNode> H(m);
MachineNode x;
for(int i=1;i<=m;i++)
{
x.avail=0;
x.ID=i;
H.Insert(x);
}
for(int i=n;i>=1;i--)
{
H.RemoveMin(x);
cout<<"将机器"<<x.ID<<"从"<<x.avail<<"到"<<(x.avail+a[i].time)<<"的时间段分配给作业"<<a[i].ID<<endl;
x.avail+=a[i].time;
H.Insert(x);
}
}
下面为MinHeap.h中的内容
//
#ifndef MINHEAP_h
#define MINHEAP_H
#include<iostream>
#include<stdlib.h>
using namespace std;
#define DefaultSize 20
//MinHeap堆类 最小堆的声明和定义
//即以完全二叉树的顺序存储方式来实现优先级队列
//T为关键码的类型,E为元素结点数据域的类型
template<class T,class E> //T为关键码的类型,E为元素结点的类型
class MinHeap
{
public:
MinHeap(int sz=DefaultSize);//构造函数,建立一个空堆
MinHeap(E* arr,int n); //构造函数,通过数组来建堆
~MinHeap() //析构函数,释放堆的内存空间
{delete [] heap;};
bool Insert(const E& x); //将元素x插入到最小堆中
bool RemoveMin(E& x); //删除堆顶的最小元素
bool IsEmpty()const //判断当前堆是否为空
{return currentSize==0;};
bool IsFull()const //判断当前堆是否为满
{return currentSize==maxHeapSize;};
void MakeEmpty() //把当前堆置空
{currentSize=0;};
void Display(); //显示当前堆的内容
void siftDown(); //下浮全部调整
void siftUp(); //上浮全部调整
private:
E* heap; //存放最小堆中元素的数组的首指针
int currentSize; //最小堆中当前元素的个数
int MaxHeapSize; //最小堆中最多允许的元素的个数
void siftDown(int start,int m);//从start到m下滑调整成为最小堆
void siftUp(int start); //从start到0上滑调整成最小堆
//友元重载运算浮输出堆的内容
friend ostream& operator<<(ostream& os,MinHeap<T,E> MH);
};
///MinHeap类声明结束
//构造函数
//建立一个空的最小堆,并在定义的是否指定堆的尺寸大小
//T为关键码的类型,E为元素结点的类型
template<class T,class E>
MinHeap<T,E>::MinHeap(int sz)
{
//设定堆的最多允许的元素的个数
MaxHeapSize=(DefaultSize<sz)?sz:DefaultSize;
//为堆的顺序存储结构开辟内存空间
heap=new E[MaxHeapSize];
//如果内存分配失败
if(heap==NULL)
{
cout<<"最小堆的内存分配失败!"<<endl;
exit(1);
}
//刚开始堆中的元素的个数是0个
currentSize=0;
};
构造函数结束
//带参数的构造函数
//通过数组中的元素、来创建一个堆
template<class T,class E>
MinHeap<T,E>::MinHeap(E* arr,int n)
{
//得到最大允许的元素的个数
MaxHeapSize=(DefaultSize<n)?n:DefaultSize;
//开辟最小堆的内存
heap=new E[MaxHeapSize];
//如果内存分配失败
if(heap==NULL)
{
cout<<"最小堆的内存分配失败!"<<endl;
exit(1);
};
//把参数数组中的元素一次复制到堆中
currentSize=0;
for(int i=0;i<n;i++)
Insert(arr[i]);
};
带参数的构造函数结束
//siftDown()私有成员函数
//从start到m下滑调整成为最小堆
//下滑调整的前提是当前结点的左右子树都已经成堆
template<class T,class E>
void MinHeap<T,E>::siftDown(int start,int m)
{
int i=start; //i从start开始调整
int j=2*i+1; //用于指向要和i对调的结点,先指向i的左子结点
E temp; //交换时用到的中间结点
while(j<=m) //到m时调整结束
{ //如果至少有一个子结点小于根结点,则需要调整
if(heap[j]<heap[i] || heap[j+1]<heap[i])
{ //如果左子结点大于右子结点
if(heap[j]>heap[j+1])
j=j+1; //跟较小的子结点进行位置调整
//如果根根结点更大,则要进行调整
if(heap[i]>heap[j])
{
//交换Heap[i]和Heap[j]的数据内容
temp=heap[i];
heap[i]=heap[j];
heap[j]=temp;
}
i=j; //还有从刚对调完的子结点继续调整下去
j=2*i+1;
}
else
break;
};
};
//siftDown()函数结束
//siftDown()公有成员函数
//对堆进行全部的下浮调整,只针对所有分支结点从后往前即可
template<class T,class E>
void MinHeap<T,E>::siftDown()
{
//找到最后一个还有子结点的结点
int currentPos=(currentSize-2)/2;
//从当前的currentPos依次向前进行下滑调整
while(currentPos>=0)
{
//局部自上而下地下滑调整
siftDown(currentPos,currentSize-1);
//再向前换一个分支结点
currentPos--;
};
};
//siftDown()函数结束
//siftUp()私有成员函数
//从start开始向上调整到根结点(0)
//利用了一个子结点都至多有一个父结点的特性
template<class T,class E>
void MinHeap<T,E>::siftUp(int start)
{
int i=start; //从i结点开始向上浮动调整
int j; //指向要调整的父结点
E temp; //交换用的临时变量
while(i>0)
{
//得到当前结点i的父结点的指针
if(i%2==1) //如果i是奇数结点
j=(i-1)/2; //说明i是j的左子结点
else
j=(i-2)/2; //说明i是j的右子结点
if(heap[i]<heap[j])//如果子结点小于父结点
{
//交换Heap[i]和Heap[j]的数据内容
temp=heap[i];
heap[i]=heap[j];
heap[j]=temp;
}
i=j; //继续上浮调整
}
};
siftUp()函数结束
//siftUp()公有成员函数
//对堆进行全部的上浮调整,即堆所有的叶子结点从后往前调整
template<class T,class E>
void MinHeap<T,E>::siftUp()
{
//通过上浮的方法来调整堆
//从最后一个结点进行上浮调整
int currentPos=currentSize-1;
//从后往前调整到第一个叶子结点就可以了
int end=currentSize-int((currentSize-1)/2)-1;
//从后往前对每个叶子结点进行上浮调整
while(currentPos>=end)
{
siftUp(currentPos);
currentPos--;
};
};
siftUp()函数结束
//Display()公有成员函数
//显示当前堆序列的内容
template<class T,class E>
void MinHeap<T,E>::Display()
{
//显示堆的内容
for(int i=0;i<currentSize-1;i++)
cout<<heap[i]<<" ";
};
///Display()函数结束
//友元重载输出运算符<<输出当前堆的内容
template<class T,class E>
ostream& operator<<(ostream& os,MinHeap<T,E> MH)
{
//显示堆中的内容
for(int i=0;i<MH.currentSize;i++)
os<<MH.heap[i]<<" ";
cout<<endl;
return os;
};
//<<友元重载结束
//Insert()公有成员函数
//在堆的尾部插入一个元素,并进行重新调整
template<class T,class E>
bool MinHeap<T,E>::Insert(const E& x)
{
//如果堆中的元素已经满了
if(currentSize==MaxHeapSize)
{
cout<<"堆的空间已经满了!"<<endl;
return false;
}
//把新元素先放在最后一个位置
heap[currentSize]=x;
currentSize++;
//对堆进行重新调整,只要对最后一个结点作一次上浮调整即可
siftUp(currentSize-1);
return true;
};
Insert()函数结束
//RemoveMin()公有成员函数
//删除堆顶的最小的结点,并进行再次调整
//(只需对新堆顶作一次下沉调整即可)
template<class T,class E>
bool MinHeap<T,E>::RemoveMin(E& x)
{
//如果堆中的元素已经没有了
if(currentSize==0)
{
cout<<"堆中已经没有元素了!"<<endl;
return false;
}
//删除堆顶的元素
x=heap[0];
//把最后一个元素替换到堆顶的位置
heap[0]=heap[currentSize-1];
//现存的元素个数减一
currentSize--;
//对堆顶元素作一次下沉调整即可
siftDown(0,currentSize-1);
return true;
};
/RemoveMin()函数结束
#endif