数据结构顺序队列

对队列进行

1.入队列

2.出队列

3.取队首元素

队列先进先出,允许在一端进行插入操作,另一端进行删除操作。允许插入的一端称为队尾,允许删除的一端称为队首。我们head和tail标记队首和队尾。出队列时,将head向后移动,入队列时,将tail向后移动,再给tail赋值。为了方便判断队列是否满了,我们让head指向头部,tail指向队列最后一个元素的下一个位置,[head,tail)。

tail移动到最后的位置,其实还可以插入元素,因为在进行入队列的同时可能也在进行出队列。再将tail移到队首,只要head和tail不重合,就可以插入元素。head在前,tail在后,元素在head和tail之间;tail在前,head在后,元素在head,tail之外。head和tail重合,既可表示空队列,又可表示满队列。为了避免上述情况,我们用以下两种方法表示:<1>tail==head时,表示空队列。tail->next==head,表示满队列,这样会浪费一个空间。<2>设size,如果size==0,表示空队列,如果size等于数组最大长度,表示满队列。以上两种方法都可行,为了方便,在这里我们用第二种。

seqqueue.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stddef.h>
typedef char SeqQueueType;
typedef struct SeqQueue{
SeqQueueType* data;//指针类型,使内存可以动态管理
size_t head;
size_t tail;
size_t size;//有效元素的个数
size_t capacity;//data这段内存能容纳的元素个数
}SeqQueue;
void SeqQueueInit(SeqQueue* seqqueue);//初始化函数
void SQDestroy(SeqQueue* seqqueue);//销毁函数
void SQPrintChar(SeqQueue* seqqueue,const char* msg);//打印函数
void SeqQueuePush(SeqQueue* seqqueue, SeqQueueType value);//往队列插入元素
void SeqQueuePop(SeqQueue* seqqueue);//从队列取出元素
int SeqQueueFront(SeqQueue* seqqueue, SeqQueueType* value);//取队首元素

seqqueue.c

#include "seqqueue.h"
void SeqQueueInit(SeqQueue* seqqueue){//初始化函数
if (seqqueue == NULL){
//非法输入
return;
}
seqqueue->size = 0;
seqqueue->head = 0;
seqqueue->tail = 0;
seqqueue->capacity = 1000;
seqqueue->data = (SeqQueueType*)malloc(seqqueue->capacity*sizeof(SeqQueueType));//给这1000个元素分配对应的内存
}
void SQDestroy(SeqQueue* seqqueue){
if (seqqueue == NULL){
//非法输入
return;
}
seqqueue->size = 0;
seqqueue->head = 0;
seqqueue->tail = 0;
seqqueue->capacity = 0;
free(seqqueue->data);
}
void SQPrintChar(SeqQueue* seqqueue,const char* msg){//打印函数
if (seqqueue == NULL){
//非法输入
return;
}
printf("[%s]\n", msg);
printf("队首 ");
size_t i = seqqueue->head;
for (; i < seqqueue->tail; i++){
printf("[%c] ", seqqueue->data[i]);
}
printf("队尾\n");
}
void SQReSize(SeqQueue* seqqueue){
if (seqqueue == NULL){
return;
}
if (seqqueue->size < seqqueue->capacity){
//队列没满
return;
}
seqqueue->capacity = seqqueue->capacity * 2 + 1;
//*2:与STL风格保持一致,+1:当capacity为0时,也可以扩容
SeqQueueType* new = (SeqQueueType*)malloc(seqqueue->capacity*sizeof(SeqQueueType));
//再把之前的数据挪到新的队列中
size_t i = 0;
for (; i < seqqueue->size; i++){
new[i] = seqqueue->data[i];
}
free(seqqueue->data);
seqqueue->data = new;
}
void SeqQueuePush(SeqQueue* seqqueue, SeqQueueType value){//往队列插入元素
if (seqqueue == NULL){
//非法输入
return;
}
if (seqqueue->size >= seqqueue->capacity){
//队列满了
//SQReSize(seqqueue);
return;
}
seqqueue->data[seqqueue->tail++] = value;
//tail向后移动,再把value赋给data
if (seqqueue->tail >= seqqueue->capacity){
//tail越界,但是队列没满,让它回到最开始的位置
seqqueue->tail = 0;
}
++seqqueue->size;
}
void SeqQueuePop(SeqQueue* seqqueue){//从队列取出元素
if (seqqueue == NULL){
//非法输入
return;
}
if (seqqueue->size == 0){
//空队列;
return;
}
++seqqueue->head;
if (seqqueue->head >= seqqueue->capacity){
//head越界,让它指向最开始的位置
seqqueue->head = 0;
}
--seqqueue->size;
}
int SeqQueueFront(SeqQueue* seqqueue, SeqQueueType* value){//取队首元素
if (seqqueue == NULL||value == NULL){
//非法输入
return 0;
}
if (seqqueue->size == 0){
//空队列
return 0;
}
*value = seqqueue->data[seqqueue->head];
return 1;

}

test.c

#include "seqqueue.h"
#define TEST_HEADER printf("\n=========================%s=========================\n",__FUNCTION__);
void TestInit(){
TEST_HEADER;
SeqQueue seqqueue;
SeqQueueInit(&seqqueue);
}
void Test(){
TEST_HEADER;
SeqQueue seqqueue;
SeqQueueInit(&seqqueue);
SeqQueuePush(&seqqueue, 'a');
SeqQueuePush(&seqqueue, 'b');
SeqQueuePush(&seqqueue, 'c');
SeqQueuePush(&seqqueue, 'd');
SQPrintChar(&seqqueue, "插入四个元素进队列");
SeqQueueType value;
int ret = SeqQueueFront(&seqqueue,&value);
printf("expect ret is 1,actual is %d\n", ret);
printf("expect value is a,actual is %c\n", value);
printf("\n");


SeqQueuePop(&seqqueue);
SeqQueuePop(&seqqueue);
SQPrintChar(&seqqueue, "出队列两个元素");
ret = SeqQueueFront(&seqqueue, &value);
printf("expect ret is 1,actual is %d\n", ret);
printf("expect value is c,actual is %c\n", value);
printf("\n");


SeqQueuePop(&seqqueue);
SeqQueuePop(&seqqueue);
SQPrintChar(&seqqueue, "再出队列两个元素");
ret = SeqQueueFront(&seqqueue, &value);
printf("expect ret is 0,actual is %d\n", ret);
printf("\n");


SeqQueuePop(&seqqueue);
SQPrintChar(&seqqueue, "尝试对空队列出元素");


}
int main(){
TestInit();
Test();
getchar();
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40995354/article/details/79930887
今日推荐