一步一步学数据结构之1--1(队列--两个栈实现)
单纯的用线性表或者单链表实现队列已经不足为奇,现在给大家介绍个有特色的,用两个栈实现队列。
如图
这里介绍队列的常用操作:
l 创建队列
l 销毁队列
l 清空队列
l 入队
l 出队
l 返回队首元素
l 返回队的大小
代码总分为三个文件:
SQueue.h : 放置功能函数的声明,以及表的声明
SQueue.c : 放置功能函数的定义,以及表的定义
Main.c : 主函数,使用功能函数完成各种需求,一般用作测试
整体结构图为:
这里详细说下入队操作,出队操作和返回队首元素操作:
入队操作:
如图:
出队操作:
如图:
返回队首元素:
如图:
OK! 上代码:
SQueue.h :
#ifndef _SQUEUE_H_ #define _SQUEUE_H_ typedef void SQueue; SQueue* SQueue_Create(); void SQueue_Destroy(SQueue* queue); void SQueue_Clear(SQueue* queue); int SQueue_Append(SQueue* queue, void* item); void* SQueue_Retrieve(SQueue* queue); void* SQueue_Header(SQueue* queue); int SQueue_Length(SQueue* queue); #endif
SQueue.c :
#include <stdio.h> #include <malloc.h> #include "LinkStack.h" #include "SQueue.h" typedef struct _tag_SQueue { LinkStack* inStack; LinkStack* outStack; }TSQueue; SQueue* SQueue_Create() { TSQueue* ret = (TSQueue*)malloc(sizeof(TSQueue)); if(NULL != ret) { ret->inStack = LinkStack_Create(); ret->outStack = LinkStack_Create(); if((NULL == ret->inStack) || (NULL == ret->outStack)) { LinkStack_Destroy(ret->inStack); LinkStack_Destroy(ret->outStack); free(ret); ret = NULL; } } return ret; } void SQueue_Destroy(SQueue* queue) { SQueue_Clear(queue); free(queue); } void SQueue_Clear(SQueue* queue) { TSQueue* sQueue = (TSQueue*)queue; if(NULL != sQueue) { LinkStack_Clear(sQueue->inStack); LinkStack_Clear(sQueue->outStack); } } int SQueue_Append(SQueue* queue, void* item) { TSQueue* sQueue = (TSQueue*)queue; int ret = 0; if(NULL != sQueue) { ret = LinkStack_Push(sQueue->inStack, item); } return ret; } void* SQueue_Retrieve(SQueue* queue) { TSQueue* sQueue = (TSQueue*)queue; void* ret = NULL; if(NULL != sQueue) { if(0 == LinkStack_Size(sQueue->outStack)) { while(0 < LinkStack_Size(sQueue->inStack)) { LinkStack_Push(sQueue->outStack, LinkStack_Pop(sQueue->inStack)); } } ret = LinkStack_Pop(sQueue->outStack); } return ret; } void* SQueue_Header(SQueue* queue) { TSQueue* sQueue = (TSQueue*)queue; void* ret = NULL; if((NULL != sQueue) && (0 < SQueue_Length(queue))) { if(0 == LinkStack_Size(sQueue->outStack)) { while(0 < LinkStack_Size(sQueue->inStack)) { LinkStack_Push(sQueue->outStack, LinkStack_Pop(sQueue->inStack)); } } ret = LinkStack_Top(sQueue->outStack); } return ret; } int SQueue_Length(SQueue* queue) { TSQueue* sQueue = (TSQueue*)queue; int ret = -1; if(NULL != sQueue) { ret = LinkStack_Size(sQueue->inStack) + LinkStack_Size(sQueue->outStack); } return ret; }
Main.c :
#include <stdio.h> #include <stdlib.h> #include "SQueue.h" int main(void) { SQueue* queue = SQueue_Create(); int a[10]; int i = 0; for(i=0; i<10; i++) { a[i] = i+1; SQueue_Append(queue, a+i); } printf("Length: %d\n", SQueue_Length(queue)); printf("Header: %d\n", *(int*)SQueue_Header(queue)); for(i=0; i<5; i++) { printf("Retrieve: %d\n", *(int*)SQueue_Retrieve(queue)); } printf("Header: %d\n", *(int*)SQueue_Header(queue)); printf("Length: %d\n", SQueue_Length(queue)); for(i=0; i<10; i++) { a[i] = i+1; SQueue_Append(queue, a+i); } while(SQueue_Length(queue) > 0) { printf("Retrieve: %d\n", *(int*)SQueue_Retrieve(queue)); } SQueue_Destroy(queue); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)