offer2
题目:定义栈的数据结构,要求添加一个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;
}
offer18
用两个栈来实现一个队列
可以用一个栈始终作为入队元素的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);
}
}
offer24
http://zhedahht.blog.163.com/blog/static/25411174200732102055385/ 还不太懂,编译完再搞明白
offer39
用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1在栈顶。颠倒之后的栈为{5, 4, 3, 2, 1},5处在栈顶。
题目没什么意思,没写代码。