题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。
方法,定义一个辅助栈,在正常栈里实现push和pop操作时,每次都更新辅助栈的信息,辅助栈的栈顶存放着当前栈中的最小值,当push时检查push进的值,如果比栈顶(push前的最小值)小,那么辅助栈入栈push的值,否则,辅助栈入栈栈顶值(最小值还是push之前的),pop的时候直接pop辅助栈即可。辅助栈是从空栈一步步建立起来的,类似动态规划,每一次push之前的信息都已经保存了。
代码:
typedef struct A { int data; struct A *next; }list; typedef struct B { list *top; list *min_top;//辅助栈保存最小值信息 }stack; void push(int n,stack *s) { list *p=(list*)malloc(sizeof(list));//正常栈入栈元素 p->next=NULL; p->data=n; list *pm=(list*)malloc(sizeof(list));//辅助栈入栈元素 pm->next=NULL; pm->data=n; if(s->top==NULL)//空栈直接入栈 { s->top=p; s->min_top=pm; } else //栈非空 { p->next=s->top; //正常栈直接入栈 s->top=p; pm->next=s->min_top; s->min_top=pm; if(s->min_top->data > s->min_top->next->data)//辅助栈待入栈元素与栈顶元素比较 s->min_top->data = s->min_top->next->data; } } int pop(stack *s) { if(s->top==NULL) exit(0); int n=s->top->data; list *p=s->top; s->top=p->next; free(p); p=s->min_top; s->min_top=s->min_top->next; free(p); return n; }
用两个栈来实现一个队列
可以用一个栈始终作为入队元素的push,当出队时,先将栈1的元素挨个pop到栈2中,然后执行栈2的pop就是出队,出队完毕后,在将栈2中的元素挨个pop到栈1中。原文中是在类中用c++实现的,这里用c实现,c++还不熟
代码:
#include <stdio.h> #include <stdlib.h> typedef struct A{ int data; struct A* pNext; }Node; //栈结点 typedef struct B{ Node * pTop; Node * pBottom; }Stack; //栈,有一个空闲的栈底 typedef struct C { Stack S1; Stack S2; }Queue; //两个栈组成的队列 void InitStack(Stack* pStack) //初始化栈 { Node * pNew=(Node*)malloc(sizeof(Node)); if(pNew==NULL){ printf("分配失败\n"); exit(-1); } pNew->pNext=NULL; pStack->pBottom=pStack->pTop=pNew; return; } void push(Stack* pStack,int val){ Node * pNew=(Node*)malloc(sizeof(Node)); if(pNew==NULL){ printf("分配失败\n"); exit(-1); } pNew->data=val; pNew->pNext=pStack->pTop; pStack->pTop=pNew; return; } bool is_empty(Stack* pStack){ if(pStack->pBottom==pStack->pTop) return true; else return false; } bool pop(Stack* pStack,int &val){ if(is_empty(pStack)){ return false; } else{ val=pStack->pTop->data; Node* p=pStack->pTop; pStack->pTop=pStack->pTop->pNext; free(p); return true; } } void InitQueue(Queue* pQueue) { InitStack(&pQueue->S1); InitStack(&pQueue->S2); } void EnQueue(Queue *pQueue, int val) { push(&pQueue->S1, val); } bool OutQueue(Queue *pQueue, int &val) { int temp; //将栈S1的元素挨个pop到S2中 while (pop(&pQueue->S1, temp)) push(&pQueue->S2, temp); //S2出栈 if (pop(&pQueue->S2, val)) { //再将S2中元素挨个pop到S1中 while (pop(&pQueue->S2, temp)) push(&pQueue->S1, temp); return true; } return false; } int main(void) { Queue Q; InitQueue(&Q); int i,val; for (i=0;i<10;i++) EnQueue(&Q, i); for (i=0;i<10;i++) { if (OutQueue(&Q, val)) printf("%3d ",val); } }
http://zhedahht.blog.163.com/blog/static/25411174200732102055385/ 还不太懂,编译完再搞明白
用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1在栈顶。颠倒之后的栈为{5, 4, 3, 2, 1},5处在栈顶。
题目没什么意思,没写代码。