最大最小优先队列

需求分析

最大最小优先队列:

优先队列是0个或多个元素的集合,每个元素都有一个优先权或值,以队列形式存放数据,因此只允许底端加入数据,顶端取出数据,数据的排列按照优先权或值的大小排列。需要实现以下操作:

1、   查找:找出队列中最小或最大元素。

2、   删除:删除队列中最大或最小元素。

3、   插入:插入新元素到队列中。

4、   查看:查看整个队列的所有数据。

5、   实现以上操作后的队列,仍然要为最小或最大优先队列。

 

算法原理介绍

以线性表的形式存放数据,只允许在第一个元素前插入数据。

利用堆排序算法将队列调整成优先队列。

实现查找、删除、插入等操作。

主要算法:

voidHeapAdjust2(SqList&L,int s,int m)//堆调整算法2(最大优先队列)

{

       int j,rc;

       rc=L.elem[s];

       for(j=2*s;j<=m;j*=2) \\一次堆调整,使小局部顶端为最大元素

       {

              if(j<m&&L.elem[j]>L.elem[j+1])++j;

              if(rc<L.elem[j])break;

              L.elem[s]=L.elem[j];

              s=j;

 

       }

       L.elem[s]=rc;

}

 

voidHeapSort2(SqList&L)//堆排序算法2(最大优先队列)

{

       int i,t;

       for(i=L.length/2;i>0;--i)

HeapAdjust2(L,i,L.length); \\由L.length/2 个元素开始进行堆调整

 

       for(i=L.length;i>1;--i)

       {

              t=L.elem[i];

              L.elem[i]=L.elem[1]; \\由L.length/2到第2个元素进行堆调整,最

                        \\终使整个队列完成堆排序,形成最大堆

 

              L.elem[1]=t;

              HeapAdjust2(L,1,i-1);

       }

 

}

 

实现过程

 

#include<stdio.h>

#include<malloc.h>

#include<stdlib.h>

#include"windows.h"

#define ElemType int

#define list_init_size  10000

#define LISTINCREMENT   10

#define OK 1

#define ERROR 0

 

typedef struct

{

       ElemType*elem;

       intlength;

       intlistsize;

}SqList;

int InitList_Sq(SqList &L)//初始化线性表

int ListInsert(SqList&L,int i,ElemTypee)//线性表插入操作

int ListDelete(SqList &L,int i,ElemType&e)//线性表删除操作

int ListLoad(SqList&L)//读取线性表数据

void HeapAdjust1(SqList&L,int s,int m)//堆调整算法1(最小优先队列)

{

       intj,rc;

       rc=L.elem[s];

       for(j=2*s;j<=m;j*=2)

       {

              if(j<m&&L.elem[j]<L.elem[j+1])++j;

              if(rc>L.elem[j])break;

              L.elem[s]=L.elem[j];

              s=j;

 

       }

       L.elem[s]=rc;

}

void HeapAdjust2(SqList&L,int s,int m)//堆调整算法2(最大优先队列)

{

       intj,rc;

       rc=L.elem[s];

       for(j=2*s;j<=m;j*=2)

       {

              if(j<m&&L.elem[j]>L.elem[j+1])++j;

              if(rc<L.elem[j])break;

              L.elem[s]=L.elem[j];

              s=j;

 

       }

       L.elem[s]=rc;

}

 

 

void HeapSort1(SqList&L)//堆排序算法1(最小优先队列)

{

       inti,t;

       for(i=L.length/2;i>0;--i)HeapAdjust1(L,i,L.length);

       for(i=L.length;i>1;--i)

       {

              t=L.elem[i];

              L.elem[i]=L.elem[1];

              L.elem[1]=t;

              HeapAdjust1(L,1,i-1);

       }

 

}

void HeapSort2(SqList&L)//堆排序算法2(最大优先队列)

{

       inti,t;

       for(i=L.length/2;i>0;--i)HeapAdjust2(L,i,L.length);

       for(i=L.length;i>1;--i)

       {

              t=L.elem[i];

              L.elem[i]=L.elem[1];

              L.elem[1]=t;

              HeapAdjust2(L,1,i-1);

       }

 

}

 

void printmainmenu()                               //主菜单

 

 

void Min(SqList &L)//最小优先序列实现函数

{

       inti,a,e,x,choice;

      

       while(1)

       {

       printmainmenu();

      

       scanf("%d",&choice);

       while(choice<1||choice>5)                  //保证用户正确操作

 

              {

                     printf("\n您的输入有误,请重新选择:");

                     scanf("%d",&choice);

                    

              }

       switch(choice)             //选择菜单

       {

       case1:    printf("请确定要录入的数据个数:");

                     scanf("%d",&a);

                     printf("inputdata:\n");

                     for(i=0;i<a;i++)

                            {

                                   scanf("%d",&e);

                                   ListInsert(L,1,e);

                            }

                     HeapSort1(L);

                     getchar();ListLoad(L);

                     printf("录入成功按任意键返回~");

                     getchar();break;

       case2: if(L.length==0){printf("队列为空插入失败(按任意键返回)");getchar();}

                     else{printf("请输入数据:");scanf("%d",&a);

                     ListInsert(L,1,a);HeapSort1(L);getchar();ListLoad(L);printf("插入成功按任意键返回~");}getchar();break;

       case3:    ListDelete(L,1,e);

                     if(L.length!=0){

                            printf("\ndeletethe data :%d\n",e);

                     getchar();

                     ListLoad(L);

                     printf("删除成功按任意键返回~");}

                     getchar();break;

       case4:ListLoad(L);getchar();

                     printf("按任意键返回~");

                     getchar();break;

       case5:exit(1);break;

       }

       }

}

 

 

 

void Max(SqList &L)//最大优先序列实现函数

{

 

       inti,a,e,x,choice;

   while(1){

       printmainmenu();

      

       scanf("%d",&choice);

       while(choice<1||choice>5)                  //保证用户正确操作

 

              {

                     printf("\n您的输入有误,请重新选择:");

                     scanf("%d",&choice);

                    

              }

       switch(choice)             //选择菜单

       {

       case1:    printf("请确定要录入的数据个数:");

                     scanf("%d",&a);

                     printf("inputdata:\n");

                     for(i=0;i<a;i++)

                            {

                                   scanf("%d",&e);

                                   ListInsert(L,1,e);

                            }

                     HeapSort2(L);

                     getchar();ListLoad(L);

                     printf("录入成功按任意键返回~");

                     getchar();break;

       case2: if(L.length==0){printf("队列为空插入失败(按任意键返回)");getchar();}

                     else{printf("请输入数据:");scanf("%d",&a);

                     ListInsert(L,1,a);HeapSort2(L);getchar();ListLoad(L);printf("插入成功按任意键返回~");}getchar();break;

       case3:    ListDelete(L,1,e);

                     if(L.length!=0){

                            printf("\ndeletethe data :%d\n",e);

                     getchar();

                     ListLoad(L);

                     printf("删除成功按任意键返回~");}

                     getchar();break;

       case4:ListLoad(L);getchar();

                     printf("按任意键返回~");

                     getchar();break;

       case5:exit(1);break;

       }

       }

}

 

void main()

{

       SqListL;

       inti,a,e,x,choice;

       InitList_Sq(L);

       printf("OK");

       system("cls");

      

       printf("\n\t**********************模式选择****************************\n");

       printf("\t***                                                      ***\n");

       printf("\t***                                                      ***\n");

       printf("\t***                   1——最大优先队列操作               ***\n");

       printf("\t***                                                      ***\n");

       printf("\t***                                                      ***\n");

       printf("\t***                   2——最小优先队列操作               ***\n");

       printf("\t***                                                       ***\n");

       printf("\t***                                                      ***\n");

       printf("\t***                   0——退出                           ***\n");

       printf("\t***                                                       ***\n");

       printf("\t*************************************************************\n");

       printf("\t\t请选择您要的操作:");

       scanf("%d",&x);

       while(x<0||x>2)                                    //保证用户正确操作

       {

              printf("\n您的输入有误,请重新选择:");

              scanf("%d",&x);

       }

       switch(x)

       {

       case1:Max(L);break;

       case2:Min(L);break;

       case0:exit(1);break;

       }

       getchar();

 

 

 

 

 

}

 

 

测试:

选择模式界面。假设选择最大优先队列。

进入主界面,进行相关操作;


 

 

 选择1,对列初始化操作,当队列数据存在时,初始化失败,不进行操作直接返回主界面。


选择2,添加数据,并显示当前队列信息;当队列为空时,插入失败,不进行操作直接返回主界面。

 

选择3,删除权值最大数据,并显示当前队列信息;当队列为空时,删除失败,不进行操作直接返回主界面。

 

选择4,显示当前队列信息(按权值由大到小排列);当队列为空时,查看失败,不进行操作直接返回主界面。

 

结果分析:

算法优缺点

优点在于:

1、时间复杂度小,排序稳定

2、算法思想简单易于理解编写

3、合理地利用数据数组类型的特点

4、算法主要采用板块化函数设计,相互独立,减少了个别错误影响整个系统稳定的问题。

 

缺点在于:

1、每次删除、查找、插入操作都必须重新进行一次堆排序

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值