【学习点滴-数据结构-栈&队列】设计一个min函数的栈
来源:互联网 发布:新手淘宝客 编辑:程序博客网 时间:2024/05/01 18:30
题目描述:
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。
要求函数min,push,pop的时间复杂度都是O(1).
解法1:另外设计一个最小栈做辅助结构,记录栈中的最小元素。元素栈中保存要入栈的元素。最小栈保存当前的最小元素。那么:
1.入栈时,先入元素栈,同时与最小栈顶元素比较,如果比栈顶元素小,则最小元素入最小栈,否则,栈顶元素入最小栈。
2.出栈时,栈一和栈二同时出栈。
则相应的算法如下。
注意的是:本算法中并没有对minStack做进一步的封装。因而这里的都是使用两个栈进行操作。如要符合题目的要求,应该在外层做进一步的封装。将minStack和元素栈作为最终栈的元素。类似
struct{
SelemType *top;
SelemType *base;
elemStack s;
minStack min;
int stackSize;
}
这种结构。
算法的优点是思路清晰。缺点是需要一个辅助栈。
#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <assert.h>//栈的初始最大容量 #define STACK_MAX_SIZE 100//栈的容量增量 #define INCREAMENT 10//状态函数 #define ERROR 0#define OK 1#define SOVERFLOW -1 #define YES 1#define NO 0 typedef int Status,SElemType,ElemType;typedef struct{ SElemType *base; SElemType *top; int stackSize;//当前已经分配的空间,不是指栈中元素个数。 }sqStack;Status InitStack(sqStack &S){ //初始化栈空间,栈为空 S.base = (SElemType *)malloc(STACK_MAX_SIZE * sizeof(ElemType)); if(!S.base){ exit(SOVERFLOW); } S.top = S.base; S.stackSize = STACK_MAX_SIZE; return OK; }//如果栈不空,用e传出栈顶元素并返回OK。否则返回错误。 Status GetTop(sqStack S,SElemType &e){ if(S.top == S.base){ return ERROR; } e = *(S.top - 1); return OK; }/* * Push(S,e)向栈S中压入元素e。需要考虑的情况有: * 1.栈已经满,需要增加空间。如果无法继续增加空间,则退出。 * 2.栈未满。先压入元素,然后修改栈顶指针。 **/Status Push(sqStack &S,SElemType e){ if((S.top - S.base) >= S.stackSize){ S.base = (ElemType*)realloc(S.base,(S.stackSize + INCREAMENT) * sizeof(ElemType)); if(!S.base){ exit(SOVERFLOW); } S.top = S.base + S.stackSize; S.stackSize += INCREAMENT; } //先压入元素,然后修改指针。弹出时相反 *S.top = e; S.top ++; return OK; }/* * 弹出栈顶元素。需要注意的有: * 1.栈不空。则先修改指针,然后弹出元素并传送给e。 * 2.栈为空时,返回错误。 */ Status Pop(sqStack &S,ElemType &e){ if(S.top == S.base){ return ERROR; } //先修改指针,然后弹出元素。 S.top --; e = *S.top; return OK; }Status isEmpty(sqStack S){ if(S.top == S.base){ return YES; } return NO; }//以下几个函数是对入栈,出栈的封装。实际应用中,需要进一步对栈封装。这里没有封装。 //struct{ // elemStack s;// minStack min; //} void PushIn(sqStack &S,sqStack &min,ElemType e){ ElemType tmp; Push(S,e); if(isEmpty(min)){ Push(min,e); }else{ GetTop(min,tmp); if(tmp >= e){ Push(min,e); }else{ Push(min,tmp); } } }Status PopOut(sqStack &S,sqStack &min,ElemType &e){ if(!isEmpty(S) && !isEmpty(min)){ Pop(min,e); Pop(S,e); return OK; }else{ return ERROR; } }Status GetMin(sqStack S,sqStack min,ElemType &result){ if(!isEmpty(S) && !isEmpty(min)){ GetTop(min,result); return OK; }else{ return ERROR; } } main(){ sqStack S,min; InitStack(S); InitStack(min); int rands,rest; printf("入栈:"); for(int i = 0;i < 100;i++){ rands = rand()%1000; PushIn(S,min,rands); GetMin(S,min,rest); printf("%d -- min:%d \n",rands,rest); } printf("\n出栈:"); while(!isEmpty(S)){ PopOut(S,min,rest); printf("%d ",rest); } system("pause"); return 0; }
解法2:如果不设计另外一个辅助栈,那么可以修改栈的元素类型,增加一个min字段用于记录当前已经入栈的元素中的最小元素。
typedef int SelemType;
typedef int Status;
typedef struct{
minElement *base;
minElement *top;
int stackSize;//当前已经分配的空间,不是指栈中元素个数。
}minStack;
typedef struct{
SelemType data;
SelemType min;
}minElement;
操作的时候与一般的栈操作类似,不同的是push的时候需要同时push两个栈,且minStack中始终是当前最小元素在栈顶。
次思路的代码如下:
//代码功能,包含min函数的栈的实现。#include <stdio.h>#include <stdlib.h>#include <malloc.h>//栈的初始最大容量 #define STACK_MAX_SIZE 100//栈的容量增量 #define INCREAMENT 10//状态函数 #define ERROR 0#define OK 1#define SOVERFLOW -1 #define YES 1#define NO 0 typedef int Status,ElemType; typedef struct{ ElemType data; ElemType min; }minElement; typedef struct{ minElement *base; minElement *top; int stackSize;//当前已经分配的空间,不是指栈中元素个数。 }minStack;//typedef minElement SelemType; Status InitStack(minStack &S){ //初始化栈空间,栈为空 S.base = (minElement *)malloc(STACK_MAX_SIZE * sizeof(minElement)); if(!S.base){ exit(SOVERFLOW); } S.top = S.base; S.stackSize = STACK_MAX_SIZE; return OK; } Status GetTop(minStack S,minElement &e){ if(S.top == S.base){ return ERROR; } e = *(S.top - 1); return OK; }Status isEmpty(minStack S){ if(S.top == S.base){ return YES; } return NO; }Status Push(minStack &S,ElemType e){ if((S.top - S.base) >= S.stackSize){ S.base = (minElement*)realloc(S.base,(S.stackSize + INCREAMENT) * sizeof(minElement)); if(!S.base){ exit(SOVERFLOW); } S.top = S.base + S.stackSize; S.stackSize += INCREAMENT; } //先压入元素,然后修改指针。弹出时相反.top指针始终在顶元素的下一个位置 。与pop时候的 操作刚好相反。 //TODO minElement tmp,node; node.data = e; if(isEmpty(S)){ node.min = e; }else{ GetTop(S,tmp); node.min = tmp.min > e?e:tmp.min; } *(S.top) = node; S.top++; return OK; }Status Pop(minStack &S,minElement &e){ if(S.top == S.base){ return ERROR; } //先修改指针,然后弹出元素。top指针始终在顶元素的下一个位置 S.top --; e = *S.top; return OK; }Status getMin(minStack S,ElemType &e){ minElement tmp; if(!isEmpty(S)){ GetTop(S,tmp); e = tmp.min; return OK; }else{ return ERROR; } } main(){ minStack S; InitStack(S); int rands,min; printf("入栈:"); for(int i = 0;i < 100;i++){ rands = rand()%1000; Push(S,rands); getMin(S,min); printf("%d -- min:%d \n",rands,min); } printf("\n出栈:"); minElement minE; while(!isEmpty(S)){ Pop(S,minE); printf("%d --- %d \n",minE.data,minE.min); } system("pause"); return 0; }
- 【学习点滴-数据结构-栈&队列】设计一个min函数的栈
- 设计包含min函数的栈[数据结构]
- 设计包含min函数的栈[数据结构]
- 设计包含min函数的栈[数据结构]
- 设计包含min函数的栈[数据结构]
- 【学习点滴-数据结构-栈&队列】 颠倒一个栈。
- 【学习点滴-数据结构-栈&队列】 用两个队列模拟一个栈
- 【学习点滴-数据结构-栈&队列】 用两个栈模拟一个队列
- 解题笔记-设计包含min函数的栈[数据结构]
- 数据结构与算法-设计包含min函数的栈
- 请设计包含min函数的栈,定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素
- [LeetCode-155] Min Stack(设计一个 min 函数栈)
- 【学习点滴-数据结构-栈&队列】 链式队列的实现及应用
- 数据结构面试题1.2.3-设计包含min函数的栈[数据结构]
- 算法学习一----设计包含min函数的栈
- 包含min函数的栈[数据结构]
- 【数据结构】包含min函数的栈
- 【学习点滴-数据结构-栈&队列】 栈的应用之二:括号匹配的检测
- 作为软件工程师,你必须知道的20个常识
- 软考 数据库系统工程师 2012上半年 顺利通过!!
- C++ 读写WriteableBitmap数据方法
- print的可变参数
- Linux头文件作用&信号signal处理函数
- 【学习点滴-数据结构-栈&队列】设计一个min函数的栈
- java原型模式(Prototype)
- 端口转发
- Ruby和Python的比较
- Linux网络协议栈(二) -- 套接字缓存(socket buffer)
- 动态代理
- wget下载整个网站
- Oracle 查询历史数据
- 分布式缓存系统 Memcached