队列-结构体定义与基础操作


特点:先进先出 First In First Out (FIFO),一端只能进,一端只能出
术语:队头,队尾,空队列


1. 牺牲一个存储单元的队列

1.1 定义结构体
# define MaxSize 10
typedef struct {
	int data[MaxSize];    // 使用静态数组来存储队列元素,分配内存空间
	int rear, front;      // 定义两个指针变量指向队头和队尾
} SqQueue;                // Sq - sequence - 顺序
1.2 初始化队列

初始化队列时,默认队头队尾都指向索引为0的位置,front永远指向队头,而rear指向需要插入元素的位置

void InitSqQueue(SqQueue* Q){
	Q->front = Q->rear = 0;
}
1.3 判空

这里不是存储真实指针,只是一个指针变量,用.来表示

bool EmptySqQueue(SqQueu Q){
	return (Q.front == Q.rear);	
}
1.4 入队

MaxSize=10,当队列长度为10时,rear刚好等于10,队列满,但是如果队头出队,则队列又未满,可以通过取余的方式,Q->rear = (Q->rear+1) % MaxSize ,即队尾递增的时候,加一再取模,将无线的整数映射到有限的整数集合中,那么,当rear的下一个位置是front,队尾的下一个位置是队头,则队满,因为如果rear=front就是为判空条件,而且rear永远指向下一个可以插入的元素,条件重合,固牺牲一个存储单元

bool EnQueue(SqQueue* Q, int x){
	// 判断队满,(Q->rear + 1) % MaxSize是rear下一个要走的位置
	if (((Q->rear + 1) % MaxSize) == Q->front) {
		return false;  
	}
	Q->data[Q->rear] = x;
	Q->rear = (Q->rear + 1) % MaxSize;
	return true;
}
1.5 出队

出队操作后,front指针同样也要取模操作,为了形成循环队列

bool DeQueue(SqQueue* Q, int* x){
	// 判断队列空
	if (Q->front == Q->rear){
		return false;
	}
	*x = Q->data[Q->front];
	Q->front = (Q->front + 1) % MaxSize;
}
1.6 获取队头元素
bool GetHead(SqQueue* Q, int* x){
	if (Q->front == Q->rear){
		return false;
	}
	*x = Q->data[Q->front];
	return true;
}
1.7 判断已满
bool FullQueue(SqQueue* Q){
	return (((Q->rear + 1) % MaxSize) == Q->front);
}
1.8 获取元素个数

公式:(rear + length - front) % length

int GetNodeNum(SqQueue* Q){
	int num = (Q->rear + MaxSize - Q->front) % MaxSize;
	return num;
}

2. 满队列 - 基于队列长度

在定义结构体时,增加一个size变量来存储当前队列的长度,初始化为0,入队时长度++,出队时长度–,判空则判断长度是否等于0且头尾指针指向同个节点,判满则判断长度是否等于队列最大长度,此时队满后,rear和front也指向同个节点

// ------- [结构体] ------
# define MaxSize 10
typedef struct {
	int data[MaxSize];    
	int front, rear;	  
	int size;
} SqQueue;				 
// ------- [初始化] ------
void InitSqQueue(SqQueue* Q) {
	Q->front = Q->rear = 0;
	Q->size = 0;
}
// ------- [入队] ------
bool EnSqQueue(SqQueue* Q, int x) {
	if (Q->size == MaxSize) {
		return false;
	}
	Q->data[Q->rear] = x;
	Q->rear = (Q->rear + 1) % MaxSize;
	Q->size++;
	return true;
}
// ------- [出队] ------
bool DeSqQueue(SqQueue* Q, int* x) {
	if (Q->front == Q->rear && Q->size == 0) {
		return false;
	}
	*x = Q->data[Q->front];
	Q->front = (Q->front + 1) % MaxSize;
	Q->size--;
	return true;
}
// ------- [判空] ------
bool IsEmpty(SqQueue* Q) {
	return (Q->size == 0);
}
// ------- [判满] ------
bool IsFull(SqQueue* Q) {
	return Q->size == MaxSize; // 队列已满返回true
}
// ------- [打印] ------
void PrintQueue(SqQueue* Q) {
	if (IsEmpty(Q)) {
		printf("Queue is empty!\n");
		return;
	}
	printf("Queue elements: ");
	for (int i = 0; i < Q->size; i++) {
		printf("%d ", Q->data[(Q->front + i) % MaxSize]);
	}
	printf("\n");
}
// 测试代码
int main() {
    SqQueue queue;
    InitSqQueue(&queue); // 初始化队列

    // 入队操作
    for (int i = 0; i < 5; i++) {
        if (EnSqQueue(&queue, i)) { printf("Enqueued - 入队: %d\n", i); }
        else { printf("Queue is full!\n"); }
    }
    PrintQueue(&queue); // 打印队列元素

    // 出队操作
    int value;
    for (int i = 0; i < 3; i++) {
        if (DeSqQueue(&queue, &value)) { printf("Dequeued - 出队: %d\n", value); }
        else { printf("Queue is empty!\n"); }
    }
    PrintQueue(&queue); // 打印队列元素

    // 再次入队
    for (int i = 5; i < 10; i++) {
        if (EnSqQueue(&queue, i)) { printf("Enqueued - 入队: %d\n", i); }
        else { printf("Queue is full!\n"); }
    }
    PrintQueue(&queue); // 打印队列元素

    // 继续出队操作
    while (!IsEmpty(&queue)) {
        if (DeSqQueue(&queue, &value)) { printf("Dequeued - 出队: %d\n", value); }
    }

    PrintQueue(&queue); // 打印队列元素
    return 0;
}

3. 满队列 - 基于flag变量

每次入队时,flag=1,每次出队时,flag=0,当操作到 front=rear 时,可以依靠flag来判断最后一次操作时插入还是删除,初始化flag=0

// ------- [结构体] ------
# define MaxSize 10
typedef struct {
	int data[MaxSize];
	int front, rear;
	int flag;    
} SqQueue;
// ------- [初始化] ------
void InitSqQueue(SqQueue* Q) {
	Q->front = Q->rear = 0;
	Q->flag = 0;
}
// ------- [入队] ------
bool EnSqQueue(SqQueue* Q, int x) {
	if (Q->rear == Q->front && Q->flag == 1) {    // 队满判断
		return false;
	}
	Q->data[Q->rear] = x;
	Q->rear = (Q->rear + 1) % MaxSize;
	Q->flag = 1;
	return true;
}
// ------- [出队] ------
bool DeSqQueue(SqQueue* Q, int* x) {
	if (Q->front == Q->rear && Q->flag== 0) {    // 队空判断
		return false;
	}
	*x = Q->data[Q->front];
	Q->front = (Q->front + 1) % MaxSize;
	Q->flag = 0;
	return true;
}
// ------- [判空] ------
bool IsEmpty(SqQueue* Q) {
	return (Q->front == Q->rear && Q->flag == 0);
}
// ------- [判满] ------
bool IsFull(SqQueue* Q) {
	return (Q->front == Q->rear && Q->flag == 1);
}
// ------- [打印] ------
void PrintQueue(SqQueue* Q) {
	if (IsEmpty(Q)) {
		printf("Queue is empty!\n");
		return;
	}
	printf("Queue elements: ");
	SqQueue* pointer = Q;
	for (int i = 0; i < ((Q->rear + MaxSize - Q->front) % MaxSize); i++) {
		printf("%d ", Q->data[(Q->front + i) % MaxSize]);
	}
	printf("\n");
}
// 测试代码
int main() {
	SqQueue queue;
	InitSqQueue(&queue); // 初始化队列

	// 入队操作
	for (int i = 0; i < 5; i++) {
		if (EnSqQueue(&queue, i)) { printf("Enqueued - 入队: %d\n", i); }
		else { printf("Queue is full!\n"); }
	}
	PrintQueue(&queue); // 打印队列元素

	// 出队操作
	int value;
	for (int i = 0; i < 3; i++) {
		if (DeSqQueue(&queue, &value)) { printf("Dequeued - 出队: %d\n", value); }
		else { printf("Queue is empty!\n"); }
	}
	PrintQueue(&queue); // 打印队列元素

	// 再次入队
	for (int i = 5; i < 10; i++) {
		if (EnSqQueue(&queue, i)) { printf("Enqueued - 入队: %d\n", i); }
		else { printf("Queue is full!\n"); }
	}
	PrintQueue(&queue); // 打印队列元素

	// 继续出队操作
	while (!IsEmpty(&queue)) {
		if (DeSqQueue(&queue, &value)) { printf("Dequeued - 出队: %d\n", value); }
	}

	PrintQueue(&queue); // 打印队列元素
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值