一、顺序队列的操作(明确顺序队列中会故意少用一个元素的空间)
0)定义---循环队列的定义和一些宏定义
#include
#include
#define ElementType int//如果要修改变量类型,只需修改这里的宏定义,入队出队的printf和主函数的printf即可,因为这个代码是初学顺序队的操作
#define MaxSize 4 //明确循环队列少用了一个元素空间,实际上存放的是MaxSize-1个元素
#define LEN sizeof(SqQueue)
//循环队列,少用一个元素空间
typedef struct{
ElementType* Base;
int Head;//队头元素的下标
int Back;//队尾元素的下标
}SqQueue;
1)初始化---动态开辟一段连续的内存,并让队头队尾元素的下标为0
//初始化顺序队
void Init_SqQueue(SqQueue* queue){
queue->Base=(ElementType*)malloc(MaxSize*LEN);
if(queue->Base==NULL){
printf("初始化顺序队失败!\n");
exit(0);
}
else{
queue->Head=queue->Back=0;
printf("初始化顺序队成功!\n");
}
}
2)计算长度---注意到队头的下标不一定就是小于队尾的下标,队头的下标也不一定一直为0
//计算顺序队长度
int SqQueue_Length(SqQueue queue){
int length=(queue.Back-queue.Head+MaxSize)%MaxSize;
return length;
}
3)入队---队尾插入,时时刻刻判断队列是否满了,并打印一些信息验证是否入队正常
注意到判断是否队满代码:(queue->Back+1)%MaxSize==queue->Head
注意到入队的操作代码:queue->Base[queue->Back]=data;
注意到入队后队尾的下标偏移代码:queue->Back=(queue->Back+1)%MaxSize;
//入队--队尾插入,判断是否为满
void Enter_SqQueue(SqQueue* queue,ElementType data){
if((queue->Back+1)%MaxSize==queue->Head){
printf("入队失败,队已满!\n");
}
else{
queue->Base[queue->Back]=data;
printf("%d元素入队第%d位置成功!\n",queue->Base[queue->Back],queue->Back);
queue->Back=(queue->Back+1)%MaxSize;
printf("此时队尾元素下标是:%d\n",queue->Back);
}
}
4)出队---对头删除,时时刻刻判断队是否为空,并打印一些信息验证是否出队正常
注意到判断是否为空队代码:queue->Head==queue->Back
注意到出队操作代码:*data=queue->Base[queue->Head];
注意到对头的下标偏移代码:queue->Head=(queue->Head+1)%MaxSize;
//出队--对头删除。判断是否为空
void Out_SqQueue(SqQueue* queue,ElementType* data){
if(queue->Head==queue->Back){
printf("出队失败,队已空!\n");
}
else{
*data=queue->Base[queue->Head];
printf("第%d位置%d元素出队成功!\n",queue->Head,queue->Base[queue->Head]);
queue->Head=(queue->Head+1)%MaxSize;
printf("此时队头元素下标是:%d\n",queue->Head);
}
}
5)销毁队--释放内存后重新赋值结构体的成员,在下一次入队时要先进行初始化操作
//销毁队
void Destroy_SqQueue(SqQueue* queue){
free(queue->Base);
queue->Base=NULL;
queue->Head=queue->Back=0;
if(SqQueue_Length(*queue)==0){
printf("销毁成功!\n");
}
else{
printf("销毁失败!\n");
}
}
6)取对头元素---前提是队不能为空
注意到取队头元素的代码:return queue.Base[queue.Head];
//取对头元素
ElementType Get_SqQueue_Head(SqQueue queue){
if(queue.Head==queue.Back){
printf("队尾空,无法取对头元素!\n");
}
else{
return queue.Base[queue.Head];
}
}
二、实践
创建结构体变量
初始化顺序队
3次入队---此时不会出现队满而入队失败
计算当前长度
1次出队
计算当前长度
显示对头元素
销毁对
显示对头元素
再次初始化--为了第二次入队
4次入队---会出现队满入队失败的情况
计算当前长度
4次出队---会出现对空出队失败的情况
计算当前长度
#include
#include
#define ElementType int
#define MaxSize 4 //明确循环队列少用了一个元素空间,实际上存放的是MaxSize-1个元素
#define LEN sizeof(SqQueue)
//循环队列,少用一个元素空间
typedef struct{
ElementType* Base;
int Head;
int Back;
}SqQueue;
//初始化顺序队
void Init_SqQueue(SqQueue* queue){
queue->Base=(ElementType*)malloc(MaxSize*LEN);
if(queue->Base==NULL){
printf("初始化顺序队失败!\n");
exit(0);
}
else{
queue->Head=queue->Back=0;
printf("初始化顺序队成功!\n");
}
}
//计算顺序队长度
int SqQueue_Length(SqQueue queue){
int length=(queue.Back-queue.Head+MaxSize)%MaxSize;
return length;
}
//入队--队尾插入,判断是否为满
void Enter_SqQueue(SqQueue* queue,ElementType data){
if((queue->Back+1)%MaxSize==queue->Head){
printf("入队失败,队已满!\n");
}
else{
queue->Base[queue->Back]=data;/?????/???????????????????????
printf("%d元素入队第%d位置成功!\n",queue->Base[queue->Back],queue->Back);
queue->Back=(queue->Back+1)%MaxSize;
printf("此时队尾元素下标是:%d\n",queue->Back);
}
}
//出队--对头删除。判断是否为空
void Out_SqQueue(SqQueue* queue,ElementType* data){
if(queue->Head==queue->Back){
printf("出队失败,队已空!\n");
}
else{
*data=queue->Base[queue->Head];/??????????????????????????????
printf("第%d位置%d元素出队成功!\n",queue->Head,queue->Base[queue->Head]);
queue->Head=(queue->Head+1)%MaxSize;
printf("此时队头元素下标是:%d\n",queue->Head);
}
}
//销毁队
void Destroy_SqQueue(SqQueue* queue){
free(queue->Base);
queue->Base=NULL;
queue->Head=queue->Back=0;
if(SqQueue_Length(*queue)==0){
printf("销毁成功!\n");
}
else{
printf("销毁失败!\n");
}
}
//取对头元素
ElementType Get_SqQueue_Head(SqQueue queue){
if(queue.Head==queue.Back){
printf("队尾空,无法取对头元素!\n");
}
else{
return queue.Base[queue.Head];
}
}
int main(){
SqQueue queue;
ElementType data;
//初始化
Init_SqQueue(&queue);
printf("\n");
//入队
Enter_SqQueue(&queue,111);
Enter_SqQueue(&queue,222);
Enter_SqQueue(&queue,333);
//计算当前长度
printf("\n长度为%d\n\n",SqQueue_Length(queue));
//出队
Out_SqQueue(&queue,&data);
//计算当前长度
printf("\n长度为%d\n\n",SqQueue_Length(queue));
//取对头元素
printf("对头元素是%d\n",Get_SqQueue_Head(queue));
printf("\n");
//销毁队
Destroy_SqQueue(&queue);
//计算当前长度
printf("\n长度为%d\n\n",SqQueue_Length(queue));
printf("\n");
//销毁后再次初始化
Init_SqQueue(&queue);
printf("\n");
//再次入队--故意多一次入队
Enter_SqQueue(&queue,444);
Enter_SqQueue(&queue,555);
Enter_SqQueue(&queue,666);
Enter_SqQueue(&queue,777);
//计算当前长度
printf("\n长度为%d\n\n",SqQueue_Length(queue));
//再次出队--故意多一次出队
Out_SqQueue(&queue,&data);
Out_SqQueue(&queue,&data);
Out_SqQueue(&queue,&data);
Out_SqQueue(&queue,&data);
//计算当前长度
printf("\n长度为%d\n",SqQueue_Length(queue));
return 0;
}