现在的位置: 首页 > 综合 > 正文

剑指offer–数据结构之栈(2,18,24,39)

2013年03月29日 ⁄ 综合 ⁄ 共 2491字 ⁄ 字号 评论关闭

offer2 

题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数minpush以及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处在栈顶。

题目没什么意思,没写代码。

抱歉!评论已关闭.