堆—数据结构

       “堆”这个词最初是在堆排序中提出的,但后来就逐渐指“肥料收集存储区”,就像程序设计语言Lisp和Java中所提供的设施一样。此处堆都是指一种数据结构。

        堆亦被称为:优先队列。堆通常是一个可以被看做一颗树的数组对象。这里先联系堆排序

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
int init(int x[])
{
     int i = 0;
     while(scanf("%d",&x[i++]) != EOF);
     return i - 1;
}

//保持堆的性质,假设以left(i)和right(i) 为根的两颗树都是最大堆 
void maxHeapify(int x[],int xSize,int i) 
{
     int largest = 0;
     int left = ((i + 1) << 1) - 1;
     int right = (i + 1) << 1;
     if(left < xSize && x[left] > x[i])
          largest = left;
     else
         largest = i;
     if(right < xSize && x[right] > x[largest])
              largest = right;
     if(largest != i)
     {
       swap(x[i],x[largest]);
       maxHeapify(x,xSize,largest);
     }
}
//自底向上用maxHeapify()将x[]编程最大堆 
void buildMaxHeap(int x[],int xSize)
{
     for(int i = (xSize - 1) / 2; i >= 0; i--)
             maxHeapify(x,xSize,i);
}
void heapSort(int x[],int xSize)
{
     buildMaxHeap(x,xSize);
     for(int i = xSize - 1; i > 0; i--)
     {
             swap(x[i],x[0]);
             maxHeapify(x,i,0);
     }
}
int main()
{
     /****************************/
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    /****************************/
    int x[50];
    int xSize;
    xSize = init(x);

    heapSort(x,xSize);
    
    for(int i = 0; i < xSize; i++)
            printf("%d ",x[i]);

    /****************************/
    #ifndef ONLIINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    #endif
    /****************************/
    return 0;
}
测试通过~

使用堆实现优先级队列。诸如作业调度或事件驱动的模拟应用中,优先级队列的元素对应着应用中的对象。通常我们需要确定一个给定的队列中元素所对应的应用对象,反之亦然。当用堆来实现优先级队列时,需要在堆中的每个元素里存储对应的应用对象的 柄(handle)。对象柄的准确表示到底怎么样(如,一个指针,一个整型数等等)还取决于具体的应用。同样的,我们需要将堆中元素的柄存储到其对应的应用对象中。

下面是最大堆实现优先级队列,模拟作业调度。作业有一个优先级proority和类似一个控制块blockThing,暂时用它表示作业号。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
//堆实现最大优先队列,模拟作业调度
//作业结构:优先级int priority,控制块int block 表示 
typedef struct node
{
        int priority;
        int blockThing;
}queueJob;
void maxHeapify(queueJob A[],int aSize,int i)
{
     int largest = 0;
     int left = ((i + 1) << 1) - 1;
     int right = (i + 1) << 1;
     if(left < aSize && A[left].priority > A[i].priority)
          largest = left;
     else
         largest = i;
     if(right < aSize && A[right].priority > A[largest].priority)
              largest = right;
     if(largest != i)
     {
      swap(A[i],A[largest]);
      maxHeapify(A,aSize,largest);
     }
}
void buildMaxHeap(queueJob A[],int aSize)
{
     for(int i = (aSize - 1) / 2; i >= 0; i--)
             maxHeapify(A,aSize,i);
}
/********************************优先队列函数******************/
queueJob maximumHeap(queueJob A[]) 
{
  return A[0];
}
queueJob extractMaxHeap(queueJob A[],int& aSize)
{
  
  if(aSize < 0)
  {
    printf("heap underflow\n");
    exit(1);
  }
  queueJob max = A[0];
  A[0] = A[aSize - 1];
  aSize -= 1;
  maxHeapify(A,aSize,0);
  return max;
}
void increaseKeyHeap(queueJob A[],int aSize,int id, int k)//将第i个作业的优先级增加到k 
{
     int i = -1;
     for(int j = 0; j < aSize; j++)
     {
           if(A[j].blockThing == id)
           {
              i = j; 
              break;
           }
     }
     if(i == -1){printf("错误\n");exit(1);}
     if(k < A[i].priority)
     {
          printf("新的优先级必须高于现有的");
          exit(1);
     }
     A[i].priority = k;
     while(i > 0 && A[(i-1) / 2].priority < A[i].priority)
     {
       swap(A[i],A[(i-1) / 2]);
       i = (i - 1) / 2;
     }
}
int insertMaxHeap(queueJob A[],int aSize,queueJob key)
{
    aSize = aSize + 1;
    A[aSize - 1].priority = 0xffffffff;
    A[aSize - 1].blockThing = key.blockThing;
    increaseKeyHeap(A,aSize,key.blockThing,key.priority);
    return aSize;
    
}
int main()
{
     /****************************/
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    /****************************/
    int jobNum = 0;
    scanf("%d",&jobNum);
    queueJob* job = (queueJob*)malloc(2 * jobNum * sizeof(queueJob));
    for(int i = 0; i < jobNum; i++)
    {
      scanf("%d %d",&job[i].priority,&job[i].blockThing);
    }
    buildMaxHeap(job,jobNum);//建立最大堆
    queueJob top = maximumHeap(job);
    printf("优先级作业最大是:%d %d",top.priority,top.blockThing);
    increaseKeyHeap(job,jobNum,101,20);
    top = maximumHeap(job);
    printf("优先级作业最大是:%d %d",top.priority,top.blockThing);
    queueJob x;
    x.priority = 10;
    x.blockThing = 122;
    jobNum = insertMaxHeap(job,jobNum,x);
    printf("\n%d排序后:\n",jobNum);
    int num = jobNum;
    for(int i = 0; i < num; i++)
    {
            top = extractMaxHeap(job,jobNum);
            printf("%d %d\n",top.priority,top.blockThing);
    }
    
     
    
    /****************************/
    #ifndef ONLIINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    #endif
    /****************************/
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值