数据结构与算法分析学习笔记三-循环队列C语言实现

队列,在日常生活中有很多非常直观的例子。实际生活中的每次排队都是一个队列。今天我们就来看看循环队列的如何用简单的C语言来实现。本文中所有的代码均在anycodes.tk在线编程网站上测试通过。

队列进队,出对的操作实际上和前面讲过的栈差不多。只不过,栈进出在一端,而队列进出分别在队列的两端。所以一些基本的操作代码是非常容易看懂的,再次略过。本文着重分析在循环队列中如何进行错误控制,主要介绍两种方法。

 

1. 标志位法

这里所谓的标志位法,是指在结构体中添加一个成员变量Size,当有元素进队时,Size加一;反之,元素出对时,Size减一。因此可以通过Size和队列能容纳最多个元素Capacity比较,来确定队列满或队列空。详细见如下代码:

#include <stdio.h>  
#include <stdlib.h>  
#include <malloc.h>  
  
struct Queue;  
typedef struct Queue *pQueue;  
struct Queue  
{  
    int Capacity;             //队列中可容纳最大个数的元素  
    int Size;                 //队列中已有元素的个数
	int Rear;              //队列中进行数据插入的一端
	int Front;          //队列中进行数据删除的一端
    int *Array;          
};  
  
  
//创建队列  
void createQueue(pQueue ptrQueue, int EleNum)  
{  
	
    if (ptrQueue == NULL)  
    {  
        printf("Out of space!\n");       //分配空间失败  
        exit(1);  
    }  
    ptrQueue -> Array = malloc(sizeof(int)*(EleNum-1));      //给数组分配空间  
    if (ptrQueue -> Array == NULL)  
    {  
        printf("Out of space!\n");       //分配空间失败  
        exit(1);  
    }  
    ptrQueue -> Capacity = EleNum;  
    ptrQueue -> Size = 0;
	ptrQueue -> Rear = 0;
	ptrQueue -> Front = 0;  
}  
  
int isFull(pQueue ptrQueue)  
{  
    return ptrQueue -> Size == ptrQueue -> Capacity -1;  
}

int calRearFront(int flag, pQueue ptrQueue)
{
	if(++flag == ptrQueue -> Capacity)
		flag = 0;
	return flag;
}  
  
void Enqueue(pQueue ptrQueue, int ele)  
{  
    if(isFull(ptrQueue))  
    {  
        printf("Sorry, the queue is full!\n");  
        exit(1);  
    }  
    ptrQueue -> Rear = calRearFront(ptrQueue->Rear, ptrQueue); 
    ptrQueue -> Array[ptrQueue -> Rear] = ele;  
	ptrQueue -> Size++;
}  
  
int isEmpty(pQueue ptrQueue)  
{  
    return ptrQueue -> Size == 0;  
}  
  
int Dequeue(pQueue ptrQueue)  
{  
	int result;    
	if(isEmpty(ptrQueue))  
    {  
        printf("Sorry, the queue is blank!\n");  
        exit(1);  
    }  
	ptrQueue -> Front = calRearFront(ptrQueue -> Front, ptrQueue);
	result = ptrQueue -> Array[ptrQueue -> Front];
    ptrQueue -> Size++;
	return result;
}  
  
void freeStack(pQueue ptrQueue)  
{  
    free(ptrQueue -> Array);  
    free(ptrQueue);  
}  
  
int main()  
{  
    int a[3] = {12,4354,657};  
    int i = 0;  
    int topElement = 0; 
	int result = 0; 
    pQueue queue;  
    queue = malloc(sizeof(struct Queue));  
    createQueue(queue,4);             //创建队列  
    for (; i < 3; i++)  
    {  
        Enqueue(queue, a[i]);         //插入数值  
    }  
    //Enqueue(queue, 2);       //队列满,报错直接退出
    result = Dequeue(queue);     //移除队列中的元素
	printf("The dequeue element in the queue is %d!\n",result);                  
    freeStack(queue);  
    return 0;  
}  

在anycodes.tk在线编程网站上的测试结果:

 

2. 使用Front和Rear联系

这里说的使用Front和Rear的联系来进行判断队空和队满是指,在循环队列中,Front = Rear时,无法判断队空还是队满,为了区别这一问题,当Front = Rear表示队空,而当(Rear+1)%N = Front时,表示队满,其中N表示队列中的空格个数。大家可以画一画图,其实这个时候在队列中有一个格子是空的。好,话不多少,直接看代码。

#include <stdio.h>  
#include <stdlib.h>  
#include <malloc.h>  
  
struct Queue;  
typedef struct Queue *pQueue;  
struct Queue  
{  
    int Capacity;             //队列中可容纳最大个数的元素  
    //int Size;                 //队列中已有元素的个数
	int Rear;              //队列中进行数据插入的一端
	int Front;          //队列中进行数据删除的一端
    int *Array;          
};  
  
  
//创建队列  
void createQueue(pQueue ptrQueue, int EleNum)  
{  
	
    if (ptrQueue == NULL)  
    {  
        printf("Out of space!\n");       //分配空间失败  
        exit(1);  
    }  
    ptrQueue -> Array = malloc(sizeof(int)*(EleNum-1));      //给数组分配空间  
    if (ptrQueue -> Array == NULL)  
    {  
        printf("Out of space!\n");       //分配空间失败  
        exit(1);  
    }  
    ptrQueue -> Capacity = EleNum;  
   // ptrQueue -> Size = 0;
	ptrQueue -> Rear = 0;
	ptrQueue -> Front = 0;  
}  
  
int isFull(pQueue ptrQueue)  
{  
    return (ptrQueue -> Rear + 1) % (ptrQueue -> Capacity) == ptrQueue -> Front;  
}

void Enqueue(pQueue ptrQueue, int ele)  
{  
    if(isFull(ptrQueue))  
    {  
        printf("Sorry, the queue is full!\n");  
        exit(1);  
    }
    ptrQueue -> Rear++;  
    ptrQueue -> Array[ptrQueue -> Rear] = ele;  
}  
  
int isEmpty(pQueue ptrQueue)  
{  
    return ptrQueue -> Rear == ptrQueue -> Front;  
}  
  
int Dequeue(pQueue ptrQueue)  
{  
	int result;    
	if(isEmpty(ptrQueue))  
    {  
        printf("Sorry, the queue is blank!\n");  
        exit(1);  
    } 
	ptrQueue -> Front++; 
	result = ptrQueue -> Array[ptrQueue -> Front];
	return result;
}  
  
void freeQueue(pQueue ptrQueue)  
{  
    free(ptrQueue -> Array);  
    free(ptrQueue);  
}  
  
int main()  
{  
    int a[3] = {12,4354,657};  
    int i = 0; 
	int j = 0; 
    int topElement = 0; 
	int result = 0; 
    pQueue queue;  
    queue = malloc(sizeof(struct Queue));  
    createQueue(queue,4);             //创建队列  
    for (; i < 3; i++)  
    {  
        Enqueue(queue, a[i]);         //插入数值  
    }  
    //printStack(s);  
//   Enqueue(queue, 2);       //队列满,报错直接退出
	for (; j < 3; j++)
	{
    		result = Dequeue(queue);     //移除队列中的元素
		printf("The dequeue element in the queue is %d!\n",result);
	}                 
    //printStack(s);
	Dequeue(queue);  
    freeQueue(queue);  
    return 0;  
}  

在anycodes.tk上的测试结果 

大家可以对照测试结果图,或者自己去测试一下,帮助自己理解。

下一篇博客将是第四章树。加油加油!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值