C 队列

顺序存储

#ifndef _SEQUEUE_H_
#define _SEQUEUE_H_

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>//bool类型头文件
#include<string.h>


/*************队列的顺序存储****************/
//顺序存储 以数组为存储工具  队列遵循先进先出的规则 即出队的一端为队首
//入队的一端为队尾,类似排队  通过数组为数据存储工具 再分别定义两个变量,分别指向队尾和队首 表示其首尾的当前位置 
//两个变量都会随着出队入队的操作 位置后移),导致之前队列虽有存储位置,但后续入队 达到队列的最大值,使得入队操作无法继续进行导致的溢出,这种就是假溢出现象
//																																	(有位置 但放不下去)
//因此往往通过构建一个循环来使得空出的位置得到循环利用 解决假溢出  
//通过取模的方式 即在不满队的情况下  队尾到达队列存储的最大值之 前 进行 取模,回到存放之前存放第一个数据的位置

#define MAXSIZE 7 //队列大小
					//实际存储 6个数据
typedef int datatype ;
typedef struct sequeue{

	datatype data[MAXSIZE];//队列数组
	int front;//指向队首的前一个位置
	int rear;//指向队尾巴 
}seq_queue,*seq_pqueue;


seq_pqueue  init_sequeue(void);//队列创建 及初始化
bool insert_sequeue(seq_pqueue q,datatype data);//入队
bool quit_sequeue(seq_pqueue q,datatype *D);//出队
bool is_full_sequeue(seq_pqueue q);//判满
bool is_empty_sequeue(seq_pqueue q);//判空
void show_sequeue(seq_pqueue q);//遍历队列

#endif
#include "sequeue.h"

seq_pqueue  init_sequeue(void)//队列创建 及初始化
{
	seq_pqueue q = (seq_pqueue)malloc(sizeof(seq_queue));
	if(q == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	q->front = q->rear = MAXSIZE - 1;//初始化让它们指向队尾 (队首的前一个位置就是队尾)这也是空队的条件

	return q;
}
bool insert_sequeue(seq_pqueue q,datatype data)//入队
{
	if(is_full_sequeue(q))
	{
		return false;
	}
	q->rear = (q->rear + 1)%MAXSIZE;//尾巴后移 
	q->data[q->rear] = data;//放入数据
	return true;
}
bool quit_sequeue(seq_pqueue q,datatype *D)//出队
{
	if(is_empty_sequeue(q))
	{
		return false;
	}
	q->front = (q->front+1)%MAXSIZE;//出队 front 表示队首前一个数 i+1 表示当前数要出队
	*D = q->data[q->front];//将这个数放入D中
	return true;
}
bool is_full_sequeue(seq_pqueue q)//判满  
{
	if(q->front == (q->rear+1)%MAXSIZE)//为什么要加1 再进行取模 ?
										//因为是空队情况下(初始化) front = rear = MAXSIZE -1	
									   //又因为 满队时,队尾rear = MAXSIZE -1
									   //这就造成了空队和满队的条件是一样的
									   //,所以这里牺牲 一个存储位置作为 判定满队的条件
	{
		printf("队列已满\n");
		return true;//返回 1
	}
	return false ;

}

bool is_empty_sequeue(seq_pqueue q)//判空
{
	if(q->front == q->rear)//头尾相连  表示空即初始化状态
	{
		printf("队列已空\n");
		return true;
	}
	else 
	{
		return false;
	}
}
void show_sequeue(seq_pqueue q)//遍历队列
{
	if(is_empty_sequeue(q))
	{
		return;
	}
	int i;
	for(i = (q->front+1)%MAXSIZE;i != (q->rear+1)%MAXSIZE;i = (i+1)%MAXSIZE)//当头没有到尾 说明还有数 
															//(入队的数可能又从头开始放了)i 自然也得重头来 

		printf("%3d",q->data[i]);

		putchar(10);


}


/*链式存储/

#ifndef _LINKUEUE_H_
#define _LINKUEUE_H_

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>//bool类型头文件
#include<string.h>
typedef int datatype ;

//链式队列节点
typedef struct linkqueuenode{

	datatype data;
	struct linkqueuenode *next;
}linkqueue_node,*linkqueue_pnode;

//指向队列的头和尾
typedef struct linkueue{

	linkqueue_pnode front;//指向队首的前一个位置
	linkqueue_pnode rear;//指向队尾巴 
}link_queue,*link_pqueue;


link_pqueue  init_linkueue(void);//队列创建 及初始化
bool insert_linkueue(link_pqueue q,datatype data);//入队
bool quit_linkueue(link_pqueue q,datatype *D);//出队
bool is_empty_linkueue(link_pqueue q);//判空
void show_linkueue(link_pqueue q);//遍历队列



#endif

```c
#include "linkueue.h"

link_pqueue  init_linkueue(void)//队列创建 及初始化
{
	link_pqueue q = (link_pqueue)malloc(sizeof(link_queue));//指针域
	 q->front = (linkqueue_pnode)malloc(sizeof(linkqueue_node));//队列空间申请
	 															//初始化节点为空节点
																//为front所指向的 队首的前一个节点位置
	if(q == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	if(q->front == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	q->front->next = NULL;//空节点
	q->rear = q->front;
	return q;
}
bool insert_linkueue(link_pqueue q,datatype data)//入队
{
	linkqueue_pnode new = (linkqueue_pnode)malloc(sizeof(linkqueue_node));//队列空间申请
	if(new == NULL)
	{
		perror("malloc");
		printf("内存申请失败\n");
		exit(-1);
	}
	new->data = data;//放入数据
	new->next = NULL;//rear 指向的是当前位置

	q->rear->next = new;//前后链表相连
	q->rear = q->rear->next;//队尾指向后面
	return true;
}
bool quit_linkueue(link_pqueue q,datatype *D)//出队
{
	linkqueue_pnode  t;
	if(is_empty_linkueue(q))
	{
		return false;
	}
 	t = q->front;//front 指向的是数据的前一个位置 
	q->front = q->front->next;
	*D = q->front->data;
	free(t);//这里free掉的是链表头的front,出队的节点作为下一个链表头
	
	return true;
}

bool is_empty_linkueue(link_pqueue q)//判空
{
	if(q->front == q->rear)//头尾相连  表示空即初始化状态
	{
		printf("队列已空\n");
		return true;
	}
	else 
	{
		return false;
	}
}
void show_linkueue(link_pqueue q)//遍历队列
{
	if(is_empty_linkueue(q))
	{
		return;
	}
	linkqueue_pnode p;
		for(p = q->front->next;p!=NULL;p = p->next)//队头不为空 继续挪
		printf("%3d",p->data);
		putchar(10);
}



#include #include #include //队列最大长度 #define MAX_QUEUE 1024 //偷懒,就用静态队列了 static int mQueue[MAX_QUEUE]; //队列插入 void InsertData(int **Front, int **Rear) { if (*Rear + 1 == *Front && (*Rear + 1 - MAX_QUEUE != *Front)) { //当队列数据已满,返回 puts("Queue Size Overflow!\n"); return; } else if (*Rear - mQueue > MAX_QUEUE) { //实现的是类似循环队列,但由于是静态线性队列(数组) //而不是用链表来实现的,所以到静态队列(数组)尾部,尾指针自动指向(数组)头部 *Rear = mQueue; } puts("Input Data:"); scanf("%d", *Rear); //输入数据后,尾指针后移 *Rear += 1; } //从头指针删除一个队列中的数据 void DeleteData(int **Front, int **Rear) { if (*Front == *Rear) { //头指针尾指针重合,队列空,不能删除,返回 puts("Queue Empty!\n"); return; } else if (*Front - mQueue > MAX_QUEUE) { //参考 Rear *Front = mQueue; } //从头指针删除一个数据 *Front += 1; } //显示队列数据 void ShowData(int **Front, int **Rear) { int *temp; for (temp=*Front; temp!=*Rear; temp++) { printf("%d --> ", *temp); } puts("\n"); } void usage(void) { puts("1. Insert Data"); puts("2. Delete Data"); puts("3. Show Data"); } int main(int argc, char **argv) { //头指针,尾指针 //队列的一个特性 First in first out FIFO int *pFront, *pRear; int op_code; //初始化队列,头指针和尾指针此时指向的地址相同 pFront = pRear = mQueue; while (1) { usage(); scanf("%d", &op_code); switch (op_code) { case 1: printf("%p\n", pFront); printf("%d\n", *pFront); InsertData(&pFront, &pRear); break; case 2: DeleteData(&pFront, &pRear); break; case 3: ShowData(&pFront, &pRear); break; default: break; } } return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值