当前位置: 首页 > news >正文

数据结构——栈和队列2

3.2 用队列实现栈

typedef int QDataType;//定义队列结点的结构
typedef struct QueueNode {QDataType data;struct QueueNode* next;
}QueueNode;//定义队列的结构typedef struct Queue {QueueNode* phead;  //节点结构的指针QueueNode* ptail;  //节点结构的指针int size;          //队列有效元素个数}Queue;//初始化
void QueueInit(Queue* pq) {assert(pq);//队列里面只有phead和ptailpq->phead = pq->ptail = NULL;pq->size = 0;
}//入队列
void QueuePush(Queue* pq, QDataType x) {assert(pq);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("malloc fail!\n");exit(1);}newnode->data = x;newnode->next = NULL;//队列为空,队头队尾都是newnodeif (pq->phead == NULL){pq->phead = pq->ptail = newnode;}else {pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;}//判空
bool QueueEmpty(Queue* pq) {assert(pq);return pq->phead == NULL;  //pq->phead为空,返回true}//计算队列里面的有效元素个数
QDataType QueueSize(Queue* pq)
{//QueueNode* pcur = pq->phead;//int size = 0;//while (pcur)//{//	size++;//	pcur = pcur->next;//	//时间复杂度为O(N)//	//其余的队列接口复杂度都是O(1)//	//尝试换一种方法来实现,达到此接口的时间复杂度为O(1)//}//return size;return pq->size;
}//出队列
void QueuePop(Queue* pq) {assert(pq);//传过来的pq不为空 or 有效的队列结构assert(!QueueEmpty(pq));//空队列不可取出数据//只有一个节点if (pq->phead == pq->ptail){free(pq->phead);pq->phead = pq->ptail = NULL;}else {QueueNode* next=pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;}//取队列头数据
QDataType QueueFront(Queue* pq)
{assert(pq);//传过来的pq不为空 or 有效的队列结构assert(!QueueEmpty(pq));//空队列不可取出数据return pq->phead->data;
}//取队列尾数据
QDataType QueueBack(Queue* pq) {assert(pq);//传过来的pq不为空 or 有效的队列结构assert(!QueueEmpty(pq));//空队列不可取出数据return pq->ptail->data;
}//销毁队列
void QueueDestroy(Queue* pq) {assert(pq);QueueNode* pcur = pq->phead;while (pcur){QueueNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = pq->ptail = NULL;//将队列的两个指针置为空,防止变为野指针pq->size = 0;
}/////////////////////////上述是自己实现的队列的结构和方法///////////////////////////typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {//栈的初始化 --- 初始化两个队列//MyStack* 一位置需要返回当前栈的指针MyStack* pst=(MyStack*)malloc(sizeof(MyStack));QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;}void myStackPush(MyStack* obj, int x) {//入栈if(!QueueEmpty(&obj->q1)){// q1不为空队列,往q1里面插入数据QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}}int myStackPop(MyStack* obj) {// 出栈 --- 找空队列和非空队列Queue* emp=&obj->q1; //obj->ql类型为Queue 所以要加上&Queue* noneEmp=&obj->q2;if(QueueEmpty(&obj->q2)){emp=&obj->q2;noneEmp=&obj->q1;}//非空队列前size-1个数据往空队列里面挪动数据while(QueueSize(noneEmp)>1){QueuePush(emp,QueueFront(noneEmp));QueuePop(noneEmp);}int top=QueueFront(noneEmp);QueuePop(noneEmp);return top;}
//把不为空队列的队尾元素返回,相当于取栈顶元素
int myStackTop(MyStack* obj) {if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);}void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj); //obj 通过malloc来的,需要释放obj=NULL;
}/*** Your MyStack struct will be instantiated and called as such:* MyStack* obj = myStackCreate();* myStackPush(obj, x);* int param_2 = myStackPop(obj);* int param_3 = myStackTop(obj);* bool param_4 = myStackEmpty(obj);* myStackFree(obj);
*/

3.3 用栈实现队列

typedef int STDataType;
//定义栈的数据结构
//栈的底层结构 链表或者是数组都是可以的 但是数组的实现会更加简单(有点像顺序表) typedef struct Stack {STDataType* arr;int top;int capacity;
}Stack;//栈的初始化
void StackInit(Stack* ps) {assert(ps);ps->arr = NULL;ps->top = ps->capacity = 0;
}//栈的销毁
void StackDestroy(Stack* ps) {if (ps->arr != NULL)free(ps->arr);ps->arr = NULL;ps->top = ps->capacity = 0;}//入栈 --  栈顶  -- 顺序表的尾插
void StackPush(Stack* ps, STDataType x) 
{assert(ps);//空间不够 --- 增容if (ps->top == ps->capacity){//扩容int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail!\n");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}//空间足够 --- 直接插入数据ps->arr[ps->top] = x;ps->top++;}//判空
bool StackEmpty(Stack* ps)
{assert(ps);return ps->top == NULL;//top=NULL   返回 true//top!=NULL  返回 false
}//出栈  -- 栈顶
void StackPop(Stack* ps)
{assert(!StackEmpty(ps));ps->top--;
}//取栈顶元素
STDataType StackTop(Stack* ps) 
{assert(!StackEmpty(ps));return ps->arr[ps->top - 1];}////////////////////////上述是自己实现的栈的结构和接口实现///////////////////////////typedef struct {// 定义Stack pushST;Stack popST;} MyQueue;MyQueue* myQueueCreate() {// 初始化MyQueue* pq=(MyQueue*)malloc(sizeof(MyQueue));StackInit(&pq->pushST);StackInit(&pq->popST);return pq;}void myQueuePush(MyQueue* obj, int x) {//入队StackPush(&obj->pushST,x);}int myQueuePop(MyQueue* obj) {if(StackEmpty(&obj->popST)){//将pushST中的数据全部导入popSTwhile(!StackEmpty(&obj->pushST)){StackPush(&obj->popST,StackTop(&obj->pushST));StackPop(&obj->pushST);}}int top=StackTop(&obj->popST);StackPop(&obj->popST);return top;
}//取队头
int myQueuePeek(MyQueue* obj) {if(StackEmpty(&obj->popST)){//将pushST中的数据全部导入popSTwhile(!StackEmpty(&obj->pushST)){StackPush(&obj->popST,StackTop(&obj->pushST));StackPop(&obj->pushST);}}int top=StackTop(&obj->popST);return top;
}bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);
}void myQueueFree(MyQueue* obj) {StackDestroy(&obj->pushST);StackDestroy(&obj->popST);free(obj);obj=NULL;}

3.4 循环队列


typedef struct {//底层结构为数组int* arr;int front;//队头int rear;//队尾int capacity;//循环队列的空间大小} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* pq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));//申请k+1个空间pq->arr=(int*)malloc(sizeof(int)*(k+1));pq->front=pq->rear=0;pq->capacity=k;return pq;}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->front==obj->rear;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->rear+1)%(obj->capacity+1)==obj->front;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//向循环队列中插入数据if(myCircularQueueIsFull(obj)){return false;}obj->arr[obj->rear++]=value;// obj->rear=obj->rear%(obj->capacity+1);obj->rear %= obj->capacity+1;return true;}
//删除数据
bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return false;}//队列不为空++obj->front;obj->front %= obj->capacity+1;return true;}
//取队头
int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}//队列不为空return obj->arr[obj->front];
}
//取队尾
int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}int prev=obj->rear-1;if(obj->rear==0){prev=obj->capacity;}return obj->arr[prev];}void myCircularQueueFree(MyCircularQueue* obj) {if(obj->arr){free(obj->arr);}free(obj);obj=NULL;
}
http://www.dtcms.com/a/327862.html

相关文章:

  • JAiRouter 0.2.1 更新啦:内存优化 + 配置合并 + IP 限流增强,运维体验再升级
  • TCP/IP、socket、http
  • 5分钟精通 useMemo
  • Ubuntu-初始化环境
  • Kafka的一条消息的写入和读取过程原理介绍
  • SQL脚本--捞json数据
  • 【SpringBoot】08 容器功能 - SpringBoot底层注解汇总大全
  • CPPIO流
  • 熟悉并使用Spring框架 - XML篇
  • 深度学习自动并行技术:突破计算瓶颈的智能调度艺术
  • Qwen-OCR:开源OCR技术的演进与全面分析
  • 机器学习-决策树(上)
  • 小黑课堂计算机一级WPSOffice题库安装包1.44_Win中文_计算机一级考试_安装教程
  • VUE+SPRINGBOOT从0-1打造前后端-前后台系统-会议记录
  • 91、23种经典设计模式
  • STM32即插即用HAL库驱动系列——4位串行数码管显示
  • Pandas数据处理与分析实战:Pandas数据处理与分析入门-选择与过滤
  • uniapp -- 小程序处理与设备通讯 GBK/GB2312 编码问题。
  • 记一次 .NET 某汽车控制焊接软件 卡死分析
  • 腾讯云terraform学习教程
  • 传输线的效应
  • 【MAUI】在 .NET MAUI 中实现全局异常捕获的完整指南
  • 五、Nginx、RabbitMQ和Redis在Linux中的安装和部署
  • DAY41 简单CNN
  • PostgreSQL——数据查询
  • PyCharm Community 2024.2.3.exe 安装教程(详细步骤,附安装包下载)
  • Docker守护进程安全加固在香港VPS环境的操作标准
  • vue3使用插槽写一个自定义瀑布列表
  • 海康视觉相机驱动软件参数配置
  • 用 Docker 安装并启动 MySQL:从零到实战的完整指南