数据结构-队列04

队列概念:

队列是限制在两端进行插入操作和删除操作的线性表,允许进行存入操作的一端称为“队尾”,允许进行删除操作的一端称为“队头”。当线性表中没有元素时,称为“空队”。特点 :先进先出(FIFO)。

队列的特征:
特殊的线性表,先进先出(FIFO)。
1)数据:
对于非空的队列,表头没有直接前驱,表尾没有直接后继,其它有且仅有一个直接前驱和一个直接后继。
2)操作:
只允许在表尾插入数据,在表头删除数据

顺序队列

typedef int datatype ;	    /*定义队列中数据元素的数据类型*/
#define MAXSIZE 64		/*定义队列的容量*/
typedef struct 
{	
	datatype data[MAXSIZE] ; 	/*用数组作为队列的储存空间*/
	int	  front,rear ; 	/*指示队头位置和队尾位置的指针*/
} sequeue ; 			/*顺序队列类型定义*/
sequeue *sq ; 		/*定义指向顺序队列的指针*/
初始化

算法思路:
首先使用malloc()函数申请内存,申请成功后,设置队头和队尾。

void init_seqqueue(seq_pqueue *Q)
{
	*Q=(seq_pqueue)malloc(sizeof(seq_queue));
	if((*Q)==NULL)
	{
		perror("malloc");
		exit(-1);
	}
	(*Q)->front=(*Q)->rear=MAXSIZE-1;
	
	return;
}
判断是否为空

算法思路:当队头和队尾指针在同一位置时,队空。q->rear == q->front)

bool is_empty_seqqueue(seq_pqueue q)
{
	if(q->rear == q->front)
		return true;
	else
		return false;
}
判断是否为满

算法思路:队头指针在队尾指针的下一位置时,队满 因为队头指针可能又重新从0位置开始,而此时队尾指针是MAXSIZE - 1,所以需要求余;少用一个存储空间,也就是数组的最后一个存数空间不用

bool is_full_seqqueue(seq_pqueue q)
{
	if((q->rear+1)%MAXSIZE == q->front)
		return true;
	else
		return false;
}
入队

算法思路:首先判断队列是否满,设置rear=rear+1(队列尾指针加1,指向入队列地址),将入队元素保存在rear指向的位置

bool in_seqqueue(datatype data,seq_pqueue q)
{
	//判断队列是否满
	if(is_full_seqqueue(q)){
		printf("队列已满!\n");
		return false;
	}

	//入对
	q->rear=(q->rear+1)%MAXSIZE;
	q->data[q->rear]=data;
	return true;
}
出队

算法思路:
首先判断队列是否为空,从队列首部取出队头元素,修改队头front的序号,使其指向下一个。

bool out_seqqueue(seq_pqueue q,datatype *D)
{
	//判断队列是否空
	if(is_empty_seqqueue(q)){
		printf("队列已空!\n");
		return false;
	}

	//出队
	q->front=(q->front+1)%MAXSIZE;
	*D=q->data[q->front];

	return true;
}
遍历队列
void show_seqqueue(seq_pqueue q)
{
	int i;
	if(is_empty_seqqueue(q))
		return;
	//非空时,从对头打印到队尾
	for(i=(q->front+1)%MAXSIZE;i!=(q->rear+1)%MAXSIZE;i=(i+1)%MAXSIZE)
	{
		printf("%d\t",q->data[i]);
	}
	printf("\n");
}

test

/* 用循环队列实现如下功能:
 * 用户从键盘输入整数,程序将其入对;
 * 用户从键盘输入字母,程序将队头元素出队;
 * 并在每一次出队和入队之后打印队列元素。
 */
int main(int argc, const char *argv[])
{
	seq_pqueue q;
	datatype data,t,ret;
	
	init_seqqueue(&q);

	while(1)
	{
		printf("请输入一个整数或字符:");
		ret=scanf("%d",&data);
		
		//输入整数时,入对
		if(ret == 1)
		{
			if(in_seqqueue(data,q))
				show_seqqueue(q);
		}
		else
		{
			//输入为字符时
			if(out_seqqueue(q,&t))
			{
				printf("out:%d\n",t);
				show_seqqueue(q);
			}
			//清空输入缓冲区
			while(getchar()!='\n');
		}
	}
	return 0;
}

链式队列

typedef int datatype ;	/*定义链队列中数据元素的数据类型*/
typedef struct node
{
	datatype data ;		/*数据域*/
	struct node	*next ; 	/*链接指针域*/
} linklist ; 			/*链表元素类型定义*/
typedef struct
{
	linklist *front , *rear ; 	/*链队列指针*/
} linqueue ; 		/*链队列类型定义*/
linkqueue *q ; 		/*定义指向链队列的指针*/

在这里插入图片描述

初始化
void init_linkqueue(link_pqueue *Q)
{
	//申请front和rear的空间
	*Q=(link_pqueue)malloc(sizeof(link_queue));
	if((*Q)==NULL)
	{
		perror("malloc");
		exit(-1);
	}
	//申请头结点空间
	(*Q)->front=(linkqueue_pnode)malloc(sizeof(linkqueue_node));
	if((*Q)->front==NULL)
	{
		perror("malloc");
		exit(-1) ;
	}

	(*Q)->front->next=NULL;
	(*Q)->rear=(*Q)->front;

	return;
}
判断空
bool is_empty_linkqueue(link_pqueue q)
{
	if(q->rear == q->front)
		return true;
	else
		return false;
}
入队
bool in_linkqueue(datatype data,link_pqueue q)
{
	linkqueue_pnode  new;

	//申请数据结点空间
	new=(linkqueue_pnode)malloc(sizeof(linkqueue_node));
	if(new==NULL)
	{
		puts("入队失败!");
		return false;
	}
	//将数据存储在申请的空间
	new->data=data;
	
	//将new指向的结点插入到链式队列中
	new->next=q->rear->next;
	q->rear->next=new;
	
	//让rear指针指向新的队尾结点
	q->rear=q->rear->next;

	return true;
}
出队
bool out_linkqueue(link_pqueue q,datatype *D)
{
	linkqueue_pnode t;
	//判断队列是否空
	if(is_empty_linkqueue(q)){
		printf("队列已空!\n");
		return false;
	}

	//出队
	t=q->front;
	q->front =q->front->next;
	*D=q->front->data;
	free(t);

	return true;
}
遍历
void show_linkqueue(link_pqueue q)
{
	linkqueue_pnode p;
	if(is_empty_linkqueue(q))
		return;
	//非空时,从对头打印到队尾
	for(p=q->front->next;p!=NULL;p=p->next)
	{
		printf("%d\t",p->data);
	}
	printf("\n");
}

猜你喜欢

转载自blog.csdn.net/Set_Mode/article/details/89788552