数据结构(一)线性结构(4)队列

队列的读写顺序为先入先出,根据结构可以分为单向队列、双向队列、循环队列、双向循环队列等

这里以循环的顺序队列和单向链队列为例:

循环的顺序队列定义:

typedef struct QUEUE {
    int iData[ARRAY_SIZE];
    int iFront;
    int iRear;
}T_Queue, *PT_Queue;

iData是数据域

iFront、iRear是首尾标志变量,作为指针域

 

单向链队列定义:

typedef struct NODE {
    int iData;
    struct NODE *ptNext;
}T_Node, *PT_Node;

队列节点同链表节点定义

typedef struct QUEUE {
    PT_Node ptFront;
    PT_Node ptRear;
}T_Queue, *PT_Queue;

队列结构包含一个头指针、一个尾指针

 

队列的主要操作有:

1、判空 / 判满:int isEmpty(PT_Queue ptQueue); / int isFull(PT_Queue ptQueue);

对于循环的顺序队列,为了区分判空和判满,要么另设一个标志位,要么在数据域空出一个位置(这样队满时尾指针总在头指针的前一个位置),这里采用第二种方法,因此,判空条件为首尾指针相同,判满条件为 (iRear + 1) % ARRAY_SIZE == iFront,

对于单向链队列,判空条件为头指针与尾指针指向头节点(标志作用,不是数据节点),判满条件为空间不足
2、创建空队列:PT_Queue createQueue(void);

对于循环的顺序队列,创建空队列就是分配一块数据域和头尾指针

对于单向链队列,创建空队列只需分配一个头节点(指针域为NULL)和头尾指针,并让头尾指针指向头节点即可

3、入队:int queue(int iEle, PT_Queue ptQueue);

对于循环的顺序队列,入队时先判满,不满则尾指针加1并对ARRAY_SIZE求余,写入数据

对于单向链队列,入队时创建一个新节点,创建成功则修改数据域,并将新节点作为第一个数据节点插入链表
4、出队:int dequeue(PT_Queue ptQueue);

对于循环的顺序队列,出队时先判空,不空则头指针加1并对ARRAY_SIZE求余,读出数据

对于单向链队列,出队时先判空,不空则读出第一个数据节点的数据域,头指针指向第二个数据节点,并将第一个数据节点删除,若删除后队列为空,需要将尾指针也指向头节点(标志作用)

 

 

循环的顺序队列代码:

#include <stdio.h>
#include <stdlib.h>

#define MENU_EXIT		0
#define MENU_QUEUE		1
#define MENU_DEQUEUE	2
#define MENU_PRINT		3


#define ERR			-100


typedef struct QUEUE {
	int iData[ARRAY_SIZE];
	int iFront;
	int iRear;
}T_Queue, *PT_Queue;


int isEmpty(PT_Queue ptQueue)
{
	return (ptQueue->iFront == ptQueue->iRear) ? 1 : 0 ;
}

int isFull(PT_Queue ptQueue)
{
	return ((ptQueue->iRear + 1) % ARRAY_SIZE == ptQueue->iFront) ? 1 : 0 ;
}

void printQueue(PT_Queue ptQueue)
{
	int i = ptQueue->iFront;

	if (isEmpty(ptQueue))
	{
		printf("Queue is empty\r\n");
		return;
	}

	printf("\r\n\r\n"
			"Queue: ");
	while ( i != ptQueue->iRear)
	{
		i = (i + 1) % ARRAY_SIZE;
		printf("%d ", ptQueue->iData[i]);
	}
	printf("\r\n\r\n");

}

int queue(int iEle, PT_Queue ptQueue)
{
	if (isFull(ptQueue))
	{
		printf("Queue is full\r\n");
		return ERR;
	}

	ptQueue->iRear = (ptQueue->iRear + 1) % ARRAY_SIZE;
	ptQueue->iData[ptQueue->iRear] = iEle;
	//printf("Queue: %d\r\n", ptQueue->iData[ptQueue->iRear]);

	return iEle;
}

int dequeue(PT_Queue ptQueue)
{
	if (isEmpty(ptQueue))
	{
		printf("Queue is empty\r\n");
		return ERR;
	}

	ptQueue->iFront = (ptQueue->iFront + 1) % ARRAY_SIZE;
	//printf("Dequeue: %d\r\n", ptQueue->iData[ptQueue->iFront]);

	return ptQueue->iData[ptQueue->iFront];
}

PT_Queue createQueue(void)
{
	int iNum, i, iEle;
	PT_Queue ptQueue = NULL;

	printf("Enter num of data: ");
	scanf_s("%d", &iNum);
	if (iNum > ARRAY_SIZE - 1 || iNum < 0)
		goto done;

	ptQueue = (PT_Queue)malloc(sizeof T_Queue);
	ptQueue->iFront = ptQueue->iRear = 0;

	printf("Enter your data: ");
	for (i = 0; i < iNum; i++)
	{
		scanf_s("%d", &iEle);
		queue(iEle, ptQueue);
	}

done:
	return ptQueue;
}


int menu(PT_Queue ptQueue)
{
	int iNum, iEle;

	printf("0 to exit\r\n"
		"1 to queue\r\n"
		"2 to dequeue\r\n"
		"3 to print\r\n");

	scanf_s("%d", &iNum);
	switch (iNum)
	{
		case MENU_EXIT:
			return -1;
		case MENU_QUEUE:
			printf("Enter the one to be push\r\n");
			scanf_s("%d", &iEle);
			queue(iEle, ptQueue);
			break;
		case MENU_DEQUEUE:
			dequeue(ptQueue);
			break;
		case MENU_PRINT:
			printQueue(ptQueue);
			break;
	}

	return 0;
}


int main(void)
{
	PT_Queue ptQueue;

	ptQueue = createQueue();
	if (!ptQueue)
		return -1;

	while (1)
	{
		if (menu(ptQueue) == -1)
			break;
	}

	return 0;
}


 

 

 

单向链队列代码:

#include <stdio.h>
#include <stdlib.h>

#define MENU_EXIT		0
#define MENU_QUEUE		1
#define MENU_DEQUEUE	2
#define MENU_PRINT		3


#define ERR			-100


typedef struct NODE {
	int iData;
	struct NODE *ptNext;
}T_Node, *PT_Node;

typedef struct QUEUE {
	PT_Node ptFront;
	PT_Node ptRear;
}T_Queue, *PT_Queue;

int isEmpty(PT_Queue ptQueue)
{
	return (ptQueue->ptRear == ptQueue->ptFront) ? 1 : 0;
}

void printQueue(PT_Queue ptQueue)
{
	PT_Node ptTmp;

	if (isEmpty(ptQueue))
	{
		printf("Queue is empty\r\n");
		return;
	}

	printf("\r\n\r\n"
		"Queue: ");
	ptTmp = ptQueue->ptFront;
	while (ptTmp->ptNext && ptTmp != ptQueue->ptRear)
	{
		ptTmp = ptTmp->ptNext;
		printf("%d ", ptTmp->iData);
	}
	printf("\r\n\r\n");

}

int queue(int iEle, PT_Queue ptQueue)
{
	PT_Node ptNew;

	ptNew = (PT_Node)malloc(sizeof T_Node);
	if (!ptNew)
	{
		printf("Err in memory\r\n");
		return ERR;
	}
	ptNew->iData = iEle;
	ptNew->ptNext = NULL;
	ptQueue->ptRear->ptNext = ptNew;
	ptQueue->ptRear = ptNew;
	//printf("Queue: %d\r\n", ptQueue->iData[ptQueue->iRear]);

	return iEle;
}

int dequeue(PT_Queue ptQueue)
{
	PT_Node ptOld, ptTmp;
	int iEle;

	if (isEmpty(ptQueue))
	{
		printf("Queue is empty\r\n");
		return ERR;
	}

	ptTmp = ptQueue->ptFront;
	ptOld = ptTmp->ptNext;
	iEle = ptOld->iData;

	ptTmp->ptNext = ptOld->ptNext;
	if (!ptTmp->ptNext)
		ptQueue->ptRear = ptQueue->ptFront;
	free(ptOld);
	//printf("Dequeue: %d\r\n", ptQueue->iData[ptQueue->iFront]);

	return iEle;
}

PT_Queue createQueue(void)
{
	int iNum, i, iEle;
	PT_Queue ptQueue;
	PT_Node ptNew;

	ptQueue = (PT_Queue)malloc(sizeof T_Queue);
	if (!ptQueue)
	{
		printf("Err in memory\r\n");
		return NULL;
	}
	ptNew = (PT_Node)malloc(sizeof T_Node);
	if (!ptQueue)
	{
		free(ptQueue);
		printf("Err in memory\r\n");
		return NULL;
	}
	ptQueue->ptFront = ptQueue->ptRear = ptNew;
	ptNew->ptNext = NULL;

#if 0
	printf("Enter num of data: ");
	scanf_s("%d", &iNum);
	if (iNum < 0)
		goto done;

	printf("Enter your data: ");
	for (i = 0; i < iNum; i++)
	{
		scanf_s("%d", &iEle);
		if (!queue(iEle, ptQueue))
		{
			printf("Create successfully %d nodes\r\n", i+1);
			goto done;
		}
	}
#endif
done:
	return ptQueue;
}

int menu(PT_Queue ptQueue)
{
	int iNum, iEle;

	printf("0 to exit\r\n"
		"1 to queue\r\n"
		"2 to dequeue\r\n"
		"3 to print\r\n");

	scanf_s("%d", &iNum);
	switch (iNum)
	{
	case MENU_EXIT:
		return -1;
	case MENU_QUEUE:
		printf("Enter the one to be push\r\n");
		scanf_s("%d", &iEle);
		queue(iEle, ptQueue);
		break;
	case MENU_DEQUEUE:
		dequeue(ptQueue);
		break;
	case MENU_PRINT:
		printQueue(ptQueue);
		break;
	}

	return 0;
}

int main(void)
{
	PT_Queue ptQueue;

	ptQueue = createQueue();
	if (!ptQueue)
		return -1;

	while (1)
	{
		if (menu(ptQueue) == -1)
			break;
	}

	return 0;
}

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值