栈和队列经典题

实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间复杂度为O(1)

这道题出栈和入栈都比较好求,关键在于这个返回最小值的时间复杂度,一般来说,要遍历一遍,但是这样时间复杂度就是O(n),和题意不符,这道题的做法是创建一个结构体,这个结构体中保存着入栈元素的大小,也包含着这个栈中最小的元素,然后再创建一个结构体,这个结构体是栈,入栈的时候直接压入结构体,情况如下所示:





test.c

#include"StackAndQueuelnterview.h"
#include<Windows.h>
int main()
{
	Stack s;
	InitStack(&s);
	StackPush(&s, 5);
	StackPush(&s, 5);
	StackPush(&s, 6);
	StackPush(&s, 2);
	StackPop(&s);
	StackPush(&s, 8);
	StackPush(&s, 10);
	StackPush(&s, 50);
	//最小值应该是5
	printf("Minddata is %d", StackMindata(&s));
	system("pause");
	return 0;
}

Stacklnterview.h

#pragma once
#include<stdio.h>
#include<assert.h>
#define MAX_SIZE 100
//封装结构体,最大100个
typedef struct NewData
{
	int data;
	int Mindata;
}Newdata;

typedef struct Stack
{
	Newdata _arr[MAX_SIZE];//栈里放封装好的结构体
	int _size;
}Stack,*PStack;

//初始化
void InitStack(PStack s);
//栈顶插入元素
void StackPush(PStack s, int data);
//出栈
void StackPop(PStack s);
//返回最小元素
int  StackMindata(PStack s);


Stacklnterview.c

#include"StackAndQueuelnterview.h"
//初始化
void InitStack(PStack s)
{
	assert(s);
	s->_size = 0;
}
//栈顶插入元素
void StackPush(PStack s, int data)
{
	assert(s);
	int size = s->_size;
	if (size == MAX_SIZE)
	{
		printf("栈满了");
			return;
	}
	//如果栈是空的,最小的等于第一个元素的值
	if (size == 0)
	{
		s->_arr->data = data;
		s->_arr->Mindata = s->_arr->data;
		
		s->_size++;
		return;
	}
	if ((s->_arr + size -1)->Mindata > data)
	{
		(s->_arr + size)->Mindata = (s->_arr + size)->data = data;
		s->_size++;
		return;
	}
	//压入的元素大于上一个元素的Minddata
	else
	{
		(s->_arr + size)->Mindata = (s->_arr + size-1)->Mindata;
		(s->_arr + size)->data = data;
		 s->_size++;

	}

}
//出栈
void StackPop(PStack s)
{
	assert(s);
	if (s->_size == 0)
	{
		printf("栈为空");
		return;
	}
	s->_size--;
}
//返回最小元素
int  StackMindata(PStack s)
{
	assert(s);
	if (s->_size == 0)
	{
		printf("没有元素");
		return;
	}
	return (s->_arr + (s->_size - 1))->Mindata;
}

///////////////////////////////////////////////////////////队列/////////////////////////////////////////////////////////////////////

使用两个栈实现一个队列

思路:栈是先进后出,队列是先进先出,用两个栈来实现,先把队列的元素加到其中一个栈里,如果满了,就搬移到另外一个栈,这样栈顶元素就是队列的开始位置,以后再往进加队列元素时,先看看栈1满了没,如果没有,放到栈1中,等满了再倒入栈2,下面看图



test.c

#include"StackAndQueuelnterview.h"
//初始化队列
void QueueInit(PQueue q)
{
	assert(q);
	q->S1._size = 0;
	q->S2._size = 0;
}
//入栈
void StackPush(Stack* s, DataType data)
{
	assert(s);
	if (s->_size == MAX_SIZE)
	{
		printf("栈满了");
		return;
	}
	s->_arr[s->_size] = data;
	s->_size++;
	
}
//入队列,入到栈s1
void QueuePush(PQueue q, DataType data)
{
	assert(q);
	if (q->S1._size == MAX_SIZE)
	{
		//搬移必须保证第二个队列为空
		if (q->S2._size == 0)
		{
			while (q->S1._size != 0)
			{
				DataType data = StackTop(&(q->S1));
				StackPop(&(q->S1));
				StackPush(&(q->S2), data);
			}
		}
		else
		{
			printf("s2队列不为空");
		}
	}
	//在s1中加元素
	StackPush(&(q->S1), data);
}
//返回栈顶元素
DataType StackTop(Stack* s)
{
	assert(s);
	if (s->_size == 0)
	{
		printf("栈空了");
		return;
	}
	return s->_arr[s->_size - 1];
}
//出栈
void StackPop(Stack* s)
{
	assert(s);

	if (s->_size == 0)
	{
		printf("栈为空,操作失败!!!\n");
		return;
	}

	s->_size--;
}
//出队列
void QueuePop(PQueue q)
{
	assert(q);
	//s2不为空,直接出,顶为队列头
	if (q->S2._size > 0)
	{
		StackPop(&(q->S2));
		return;
	}
	else
	{
		//如果s1也为空,队列为空
		if (q->S1._size == 0)
		{
			printf("队为空");
			return;
		}

		//s1不为空,将s1倒过来
		else
		{
			while (q->S1._size != 0)
			{
				DataType data = StackTop(&(q->S1));
				StackPop(&(q->S1));
				StackPush(&(q->S2), data);
			}
		}
		//s2的栈顶为队头
		StackPop(&(q->S2));
	}

}
//获取队头元素
DataType QueueFront(PQueue q)
{
	assert(q);
	//s1 and s2 all empty
	if (q->S1._size == 0 && q->S2._size == 0)
	{
		printf("the queue is null");
		return 0;
	}
	if (q->S2._size != 0)
	{
		return StackTop(&(q->S2));
	}
	else
		return q->S1._arr[0];
}
//获取队尾元素
DataType QueueBack(PQueue q)
{
	assert(q);
	//如果s1,s2都是空的,说明队列是空的
	if (q->S1._size == 0 && q->S2._size == 0)
	{
		printf("the queue is null");
		return 0;
	}
	//如果s1不为空,那么队尾就是s1的栈顶,否则,就是s2的栈底
	if (q->S1._size != 0)
		return StackTop(&(q->S1));
	else
		return q->S2._arr[0];

}

StackAndQueueInterview.h

#pragma
#include<stdio.h>
#include<assert.h>

#define MAX_SIZE 9
typedef int DataType;
typedef struct Stack
{
	DataType _arr[MAX_SIZE];
	int _size;
}Stack;

typedef struct Queue
{
	Stack S1;
	Stack S2;

}Queue,*PQueue;

//初始化队列
void QueueInit(PQueue q);
//入栈
void StackPush(Stack* s, DataType data);
//入队列,入到栈s1
void QueuePush(PQueue q, DataType data);
//返回栈顶元素
DataType StackTop(Stack* s);
//出栈
void StackPop(Stack* s);
//出队列
void QueuePop(PQueue q);
//获取队头元素
DataType QueueFront(PQueue q);
//获取队尾元素
DataType QueueBack(PQueue q);

StackAndQueueInterview.c

#include"StackAndQueuelnterview.h"
//初始化队列
void QueueInit(PQueue q)
{
	assert(q);
	q->S1._size = 0;
	q->S2._size = 0;
}
//入栈
void StackPush(Stack* s, DataType data)
{
	assert(s);
	if (s->_size == MAX_SIZE)
	{
		printf("栈满了");
		return;
	}
	s->_arr[s->_size] = data;
	s->_size++;
	
}
//入队列,入到栈s1
void QueuePush(PQueue q, DataType data)
{
	assert(q);
	if (q->S1._size == MAX_SIZE)
	{
		//搬移必须保证第二个队列为空
		if (q->S2._size == 0)
		{
			while (q->S1._size != 0)
			{
				DataType data = StackTop(&(q->S1));
				StackPop(&(q->S1));
				StackPush(&(q->S2), data);
			}
		}
		else
		{
			printf("s2队列不为空");
		}
	}
	//在s1中加元素
	StackPush(&(q->S1), data);
}
//返回栈顶元素
DataType StackTop(Stack* s)
{
	assert(s);
	if (s->_size == 0)
	{
		printf("栈空了");
		return;
	}
	return s->_arr[s->_size - 1];
}
//出栈
void StackPop(Stack* s)
{
	assert(s);

	if (s->_size == 0)
	{
		printf("栈为空,操作失败!!!\n");
		return;
	}

	s->_size--;
}
//出队列
void QueuePop(PQueue q)
{
	assert(q);
	//s2不为空,直接出,顶为队列头
	if (q->S2._size > 0)
	{
		StackPop(&(q->S2));
		return;
	}
	else
	{
		//如果s1也为空,队列为空
		if (q->S1._size == 0)
		{
			printf("队为空");
			return;
		}

		//s1不为空,将s1倒过来
		else
		{
			while (q->S1._size != 0)
			{
				DataType data = StackTop(&(q->S1));
				StackPop(&(q->S1));
				StackPush(&(q->S2), data);
			}
		}
		//s2的栈顶为队头
		StackPop(&(q->S2));
	}

}
//获取队头元素
DataType QueueFront(PQueue q)
{
	assert(q);
	//s1 and s2 all empty
	if (q->S1._size == 0 && q->S2._size == 0)
	{
		printf("the queue is null");
		return 0;
	}
	if (q->S2._size != 0)
	{
		return StackTop(&(q->S2));
	}
	else
		return q->S1._arr[0];
}
//获取队尾元素
DataType QueueBack(PQueue q)
{
	assert(q);
	//如果s1,s2都是空的,说明队列是空的
	if (q->S1._size == 0 && q->S2._size == 0)
	{
		printf("the queue is null");
		return 0;
	}
	//如果s1不为空,那么队尾就是s1的栈顶,否则,就是s2的栈底
	if (q->S1._size != 0)
		return StackTop(&(q->S1));
	else
		return q->S2._arr[0];

}

判断出栈顺序是不是正确

判断的思路:一组是压栈的顺序,另一组是给的出栈的顺序,如果栈是空的,先压栈,然后和给定的出栈顺序第一个比较,如果第一个出栈的字母在栈里没有,就继续按照入栈的顺序往进入,如果有了,然后弹出,比较下一个出栈元素和栈顶是不是相等,如果不是,继续按照给定的顺序压入,以此类推,如果压到头还是没有,就说明出栈顺序是错误的!如果循环能正常结束,就说明是正确的,见图:


test.c

#include"StackAndQueuelnterview.h"

int main()
{
	stack sta;
	StackInit(&sta);
	int a[5] = { 'a','b','c','d','e' };
	int b[5] = { 'c','d','a','b','e' };
	int index = 0;
	int i = 0;
	PrintStack(&sta);
	StackInit(&sta);
	for(i = 0; i < 5; i++ )
	{
		if ((StackEmpty(&sta) != NULL) && (StackTop(&sta) == b[i]))
			StackPop(&sta);
		else  //压入元素
		{
			while (b[i] != a[index])
			{
				StackPush(&sta, a[index]);
				index++;
				if (index == 5)
				{
					printf("失败");
					system("pause");
					return;
				}
			}
			
				index++;
		}
	}
	printf("成功");
	system("pause");
	return 0;
}

StackAndQueuelnterview.h

#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#define T  10
#define MAX 100
typedef char DataType;
typedef struct Stack
{
	DataType arr[MAX];
	//int capacity;
	int size;


}stack, *PStack;






// 栈的初始化 
void StackInit(PStack ps);


// 入栈 
void StackPush(PStack ps, DataType data);


// 出栈 
void StackPop(PStack ps);
//
// 获取栈顶元素 
DataType StackTop(PStack ps);


// 获取栈中元素个数 
int StackSize(PStack ps);


// 检测栈是否为空 
int StackEmpty(PStack ps);


void PrintStack(PStack ps);//打印栈


StackAndQueuelnterview.c

#include"StackAndQueuelnterview.h"
// 栈的初始化 
void StackInit(PStack ps)
{
	assert(ps);
	ps->size = 0;
}


//入栈 
void StackPush(PStack ps, DataType data)
{
	assert(ps);
	ps->arr[ps->size] = data;
	ps->size++;
}


// 出栈 
void StackPop(PStack ps)
{
	assert(ps);
	ps->size--;
}


// 获取栈顶元素 
DataType StackTop(PStack ps)
{
	assert(ps);
	return ps->arr[ps->size - 1];

}


//获取栈中元素个数 
int StackSize(PStack ps)
{
	assert(ps);
	return ps->size;
}


//检测栈是否为空 
int StackEmpty(PStack ps)
{
	if (ps->size)
		return 1;
	else
		return 0;


}
void PrintStack(PStack ps)//打印栈
{
	int i = 0;
	for (; i < ps->size; i++)
	{
		printf("%c", ps->arr[i]);
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值