实验四 队列的基本操作

论坛 期权论坛 脚本     
匿名网站用户   2020-12-19 18:41   11   0

ZZU的学弟学妹们不要抄作业哦~(`Д)

一、实验目的

1.掌握队列存储结构的表示和实现方法。

2.掌握队列的入队和出队等基本操作的算法实现。

3.了解队列在解决实际问题中的简单应用。

二、实验内容

1.建立顺序循环队列,并在顺序循环队列上实现入队、出队基本操作。

2.建立循环链队列,并在循环链队列上实现入队、出队基本操作(选做)。

三、实验要求

1.建立顺序循环队列,并在顺序循环队列上实现入队、出队基本操作。

(1)根据输入的队列长度n和各元素值建立一个循环顺序表表示的队列(循环队列),并输出队列中各元素值。

(2)将数据元素e入队,并输出入队后的队列中各元素值。

(3)将循环队列的队首元素出队,并输出出队元素的值和出队后队列中各元素值。

2.编程实现对循环链队列的入队和出队操作。

(1)根据输入的队列长度n和各元素值建立一个带头结点的循环链表表示的队列(循环链队列),并且只设一个尾指针来指向尾结点,然后输出队列中各元素值。

(2)将数据元素e入队,并输出入队后的队列中各元素值。

(3)将循环链队列的队首元素出队,并输出出队元素的值和出队后队列中各元素值。

四、详细程序清单

//1.顺序循环队列
#include<stdio.h>
#include<stdlib.h>

#define MAXQSIZE 100
typedef struct{
 int *base;
 int front;
 int rear;
}SqQueue;
SqQueue Q; 

int Create(SqQueue &Q,int n) //创建  
{
 int e;
 Q.base=(int *)malloc(MAXQSIZE*sizeof(int)); 
 if(n>MAXQSIZE-1)  
    {  
         printf("超出最大值\n");  
         return 0;  
    }  
    Q.front=Q.rear=0;
    printf("输入队列的元素: \n");
 for(Q.rear=0;Q.rear<n;Q.rear++)  
    {   
        scanf("%d",&e);  
        Q.base[Q.rear]=e;
    }  
}  

int Show(SqQueue Q)//显示 
{
 printf("当前顺序队列元素为: "); 
    if (Q.front==Q.rear)
 {
  printf("队列为空\n"); 
  return 0;  
 }   
    int p;  
    p=Q.front;
    while (p!=Q.rear)  
    {  
        printf("%d ",Q.base[p%MAXQSIZE]); 
        p++; 
    } 
    printf("\n"); 
} 

int EnQueue(SqQueue &Q, int e)//入队列 
{ 
    if((Q.rear+1)%MAXQSIZE==Q.front) 
    {
  printf("队列满\n");
  return 0;   
    }
    Q.base[Q.rear]=e;
 Q.rear=(Q.rear+1)%MAXQSIZE;
} 

int DeQueue(SqQueue &Q)//出队列 
{
 int e;
    if (Q.front==Q.rear) 
 {
  printf("队列为空\n"); 
  return 0;    
 }  
    e=Q.base[Q.front];
    Q.front=(Q.front+1)%MAXQSIZE;
    printf("出队列元素为: %d\n",e); 
}

int main()  
{   
    int select,e,n; 
    printf("1.创建队列\t2.入队列\t3.出队列\t4.退出\n");   
    while(1)  
    { 
  printf("选择操作: ");     
        scanf("%d",&select);  
        switch(select)  
        {    
        case 1:
   printf("输入队列的长度(小于%d):  ",MAXQSIZE);  
      scanf("%d",&n);   
            Create(Q,n);
   Show(Q);  
            break;  
        case 2: 
         printf("输入入队列元素: ");
         scanf("%d",&e);  
         EnQueue(Q,e);
   Show(Q);
            break;    
  case 3: 
   DeQueue(Q);
   Show(Q);
   break; 
  case 4:  
   return 0;
        default: 
      printf("输入错误\n");
            break; 
        }  
    }  
    return 0;  
}  
//2.链循环队列(头结点为空)
#include<stdio.h>
#include<stdlib.h>

typedef struct QNode{
 int data;
 struct QNode *next;
}QNode,*LinkQueue;

LinkQueue rear,head;//尾指针和头结点,这里没有用front而是head,因为这里的头结点不是动态的,而是固定的,用head以区分顺序循环队列的front

int EnQueue(int e)//入队列 
{
 LinkQueue p;
 p=(LinkQueue)malloc(sizeof(QNode));
 p->data=e;
 rear->next=p;
    rear=p;
 rear->next=head;  
}

int Create(int n)//创建 
{
 LinkQueue p;
 int e;
 head=(LinkQueue)malloc(sizeof(QNode));
 rear=head;
 head->next=rear;
 rear->next=head;
 rear->data=head->data=NULL;
 printf("输入队列元素: ");
 while(n--)
 {
  scanf("%d",&e);
  EnQueue(e);//这里直接调用入队函数了,代码是一样的
 }

} 

int Show()//显示 
{
 LinkQueue p;
 printf("当前队列元素为: ");
 p=head->next;
 if(head==rear)//队列为空时
 {
  printf("队列为空\n");
  return 0;
 }
 for (;p!=rear;p=p->next) 
 {
  printf("%d ",p->data);
 }
 printf("%d\n",p->data);
} 
  
int DeQueue()//出队列  
{
 int e;   
    LinkQueue p; 
 p=head->next;
 e=p->data;
    if(head==rear)//队列为空时
 {
  printf("队列为空\n");
  return 0;
 }
 head->next=head->next->next;
 if(head->next==head)
 {
  rear=head;
 }
    free(p);
    printf("出队列元素为: %d\n",e);
}

int main()  
{
    int select,e,n; 
    printf("1.创建队列\t2.入队列\t3.出队列\t4.退出\n"); 
    while(1)  
    { 
  printf("选择操作: ");     
        scanf("%d",&select);  
        switch(select)  
        {    
        case 1:
   printf("输入队列的长度: "); 
      scanf("%d",&n);   
            Create(n);
   Show();  
            break;
        case 2: 
         printf("输入入队列元素: ");
         scanf("%d",&e);  
         EnQueue(e);
   Show();
            break;    
  case 3: 
   DeQueue();
   Show();
   break; 
  case 4:  
   return 0;
        default: 
      printf("输入错误\n");
            break; 
        }  
    }  
    return 0;  
}

五、程序运行结果

1.顺序循环队列:

2.链循环队列

六、实验心得体会

1.通过这次的操作,我对顺序队列中的“假上溢”有了更好的理解,让顺序队列进行循环操作可以防止“假上溢”;

2.但是对于链循环队列,我不明白为什么要让它循环,因为链队列不存在“上溢”的情况,而且队列只能尾进头出,不能像链表一样在任意位置插入新元素,所以我觉得让链队列进行循环操作好像没有意义??

3.链队列的头指针我用的是head而不是front,因为这里的头结点不是动态的,而是固定的,用head以区分顺序循环队列的动态头结点front;

4.链队列的头结点我没有赋值,是空的。开始的时候是想把头结点也赋值的,但是这样会出现很多问题:创建、入队、判空、全部出队后的重新入队都很麻烦,于是为了方便头结点没有赋值;

5.之前几次实验的运行结果看起来太乱,这次我给改简洁了;

6.错误很多,调试很烦,要有耐心。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP