【演算法設計-優先隊列】優先隊列的實現與操作,演算法隊列

來源:互聯網
上載者:User

【演算法設計-優先隊列】優先隊列的實現與操作,演算法隊列

優先隊列是堆排序的一個具體應用。

優先隊列分為如下幾個操作:

1.INSERT(S,x)把元素x插入到優先隊列中。

2.MAXIMUM(S):返回s中具有最大關鍵字的元素。

3.EXTRACT_MAX(S):去掉S中最大關鍵字的元素

4.INCREASE_KEY(S,x,k):將元素x的關鍵字值增加到k,k是不小於x的元素。

優先隊列的應用:

1.共用電腦系統的作業調度。最大優先隊列要i記錄要執行的各個作業以及他們之間的相對優先順序。當一個作業完成或者被中斷後,調度器調用EXTRACT_MAX從所有的等待作業中,選出具有最高優先順序的作業來執行。在任何時候調度器可以調用INSERT把一個新作業假如到隊列中來。

2.可以用於最小產生樹和單元最短路徑優先演算法中,需要應用DECREASE_KEY的應用。

代碼:

/*
Author:Bai 
Name:優先隊列
Use for:1.共用電腦系統中的作業調度
        2.基於事件驅動的模擬器
3.用在最小產生樹和單元最短路徑中
Date:2015/4/30
*/
#include<iostream>
using namespace std;
typedef struct heap
{
 int heap_size;
 int *key;
}heap;
void initialize(heap *A)
{
A->key=new int;
A->heap_size=0;
}
void MAX_HEAPIFY(heap *A,int i)//為了使堆保持大根堆的性質(我這裡利用了迴圈操作的方法,而演算法導論中應用了遞迴調用的辦法)
{
//非遞迴方法
int largest;
      int l=2*i;//l是A的左孩子
 int r=2*i+1;//r是A的右孩子
 if(l<=A->heap_size&&A->key[l]>A->key[i])//這裡的大於符號更改成小於符號就是小根堆排序
 largest=l;
 else 
 largest=i;
 if(r<=A->heap_size&&A->key[r]>A->key[largest])
 largest=r;
  while(largest!=i)
  {
 int temp=A->key[i];
 A->key[i]=A->key[largest];
 A->key[largest]=temp;
  i=largest;
  l=2*i;
  r=2*i+1;
     if(l<=A->heap_size&&A->key[l]>A->key[i])
    largest=l;
     else 
    largest=i;
     if(r<=A->heap_size&&A->key[r]>A->key[largest])
    largest=r;
  }
  for(int k=1;k<=A->heap_size;k++)
  printf("%d,",A->key[k]);
  printf("\n");
}
void BUILD_MAX_HEAP(heap *A)
{
int m=(A->heap_size)/2;
while(m>=1)
{
MAX_HEAPIFY(A,m);
m--;
}
}
void HEAP_SORT(heap *A)
{
BUILD_MAX_HEAP(A);
  printf("第一次建立大根堆後的數組是:");
  for(int k=1;k<=A->heap_size;k++)
  printf("%d,",A->key[k]);
  printf("\n");
int length=A->heap_size;
printf("大根堆排序後的數組是:");
printf("%d,",A->key[1]);
for(int i=length;i>=2;i--)
{
A->key[1]=A->key[i];
A->heap_size--;
MAX_HEAPIFY(A,1);//現在只有這個堆的第一個結點是錯誤的,其他的子樹都是大根堆
printf("%d ",A->key[1]);
}
printf("\n");
printf("done\n");
}
//求優先隊列的最大值
int HEAP_MAXIMUM(heap *A)
{
 printf("%d\n",A->key[1]);
 return 0;
}
//將優先隊列中去除最大值
void HEAP_EXTRACT_MAX(heap *A)
{
if(A->heap_size<1)
printf("不能再繼續刪除了!\n");
A->key[1]=A->key[A->heap_size];
A->heap_size--;
MAX_HEAPIFY(A,1);
}
//將優先隊列中的某個數m增大到key,key>m
void HEAP_INCREASE_KEY(heap *A,int i,int key)
{
A->key[i]=key;
int parent=i/2;
while(i>1&&A->key[i]>A->key[parent])//這個點增大後,要向上判斷其是否比父節點大,然後依次迴圈修改。
{
int temp=A->key[i];
A->key[i]=A->key[parent];
A->key[parent]=temp;
i=parent;
        parent=i/2;
}


}
//將key這個值插入到A優先隊列
//首先建立一個新的結點,然後將它賦值為負無窮大,最後再利用HEAP_INCREASE_KEY將它增大到key。
void HEAP_INSERT(heap *A,int key)
{
A->heap_size=A->heap_size+1;
A->key[A->heap_size]=INT_MIN;
    HEAP_INCREASE_KEY(A,A->heap_size,key);
}
void SHOW_HEAP(heap *A)
{
printf("當前的優先隊列是:\n");
for(int i=1;i<=A->heap_size;i++)
printf("%d ",A->key[i]);
printf("\n");
}
int main(void)
{
int ch;
heap *A=new heap;
initialize(A);
printf("請輸入一組堆的值以#結束?\n");
int key;
int i=1;
while(scanf("%d",&key)==1)
{
HEAP_INSERT(A,key);//插入的過程會自動建立稱為優先隊列
}
fflush(stdin);
while(1)
{
printf("***************請選擇如下操作選項***************\n");
printf("1.取優先隊列的最大值\n");
printf("2.去除優先隊列當前的最大值,去除後仍然自動變換為優先隊列結構\n");
printf("3.插入某個值,插入後仍然自動變換為優先隊列結構\n");
printf("4.把某個i點上的值增大到key\n");
printf("5.退出系統\n");
scanf("%d",&ch);
switch(ch)
{
case 1:HEAP_MAXIMUM(A);break;
case 2:

HEAP_EXTRACT_MAX(A);
break;
case 3:
{
int key;
printf("請輸入您要插入的Key值:");
scanf("%d",&key);
HEAP_INSERT(A,key);
}
SHOW_HEAP(A);
break;
case 4:
{
printf("請問您要把第幾個數變成多大?:");
int i,key;
scanf("%d %d",&i,&key);
HEAP_INCREASE_KEY(A,i,key);
}
SHOW_HEAP(A);
break;
case 5:
return 0;
default: break;
}
}
}

結果展示:






聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.