用栈实现队列

目录

  • 题目
    • 题目要求
    • 示例
  • 解答
    • 方法一、
      • 实现思路
      • 时间复杂度和空间复杂度
      • 代码

题目

用栈实现队列

题目要求

用栈实现队列_第1张图片

示例

解答

方法一、

采用两个栈,将数据入栈出栈实现数据顺序的变化。

实现思路

我们定义一个栈为pushstack,当有元素要进入队列时,都将元素放入这个栈中。
用栈实现队列_第2张图片
然后定义一个popstack栈,当有元素出队列时,我们检查popstack栈是否为空,如果为空就将pushstack栈中的元素都加入到popstack栈中。此时popstack栈中元素出栈的顺序和出队列的顺序一致。
用栈实现队列_第3张图片
当再需要有元素入队时,直接将元素放入pushstack栈中即可,而有元素出队时就将popstack栈中的元素出栈,当popstack栈为空时,再将pushstack栈中的元素都加入popstack栈中。
用栈实现队列_第4张图片

时间复杂度和空间复杂度

时间复杂度:出队时最坏为O(N),入队时为O(1)
空间复杂度:O(N)

代码

#include
#include
#include
#include
//静态数组实现栈
//#define N 10
//typedef int STDataType;
//typedef struct Stack
//{
//	STDataType a[N];
//	int top;
//}ST;

//动态数组实现栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* data;
	int top;
	int capacity;
}ST;

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

//检查栈空
bool StackEmpty(ST* ps);

//栈的销毁
void StackDestory(ST* ps);

//元素入栈
void StackPush(ST* ps, STDataType x);

//元素出栈
void StackPop(ST* ps);

//返回栈顶元素
STDataType StackTop(ST* ps);


void StackInit(ST* ps)
{
	assert(ps);
	ps->data = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

bool StackEmpty(ST* ps)
{
	assert(ps);
	/*if (ps->top <= 0)
	{
		return true;
	}
	else
	{
		return false;
	}*/

	return ps->top == 0;
}

void StackDestory(ST* ps)
{
	assert(ps);
	//将动态数组申请的空间都释放。
	free(ps->data);
	ps->data = NULL;
	ps->top = 0;
	ps->capacity = 0;
}


void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	//当栈的容量不够时
	if (ps->top == ps->capacity)
	{
		//当动态数组的大小为0时,就申请4个空间;当动态数组大小不为0时,就说明栈满了,需要扩容。
		int newCapacity = (ps->capacity == 0) ? 4 : (ps->capacity * 2);
		//给动态数组申请空间,用来存放数据
		STDataType* tmp = (STDataType*)realloc(ps->data, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->data = tmp;
		ps->capacity = newCapacity;
	}
	//将数据存到数组的末尾,然后栈顶向后移。
	ps->data[ps->top] = x;
	ps->top++;
}

void StackPop(ST* ps)
{
	assert(ps);
	//出栈时要检查栈中有没有元素,有元素才可以出栈,没有元素就不可以出栈
	assert(!StackEmpty(ps));
	ps->top--;
}

STDataType StackTop(ST* ps)
{
	assert(ps);
	//出栈时要检查栈中有没有元素,有元素才可以出栈,没有元素就不可以出栈
	assert(!StackEmpty(ps));
	return ps->data[(ps->top)-1];
}




typedef struct {
    //在该结构体中创建两个栈
    ST popstack;
    ST pushstack;
} MyQueue;


MyQueue* myQueueCreate() {
    //该函数需要申请一个MyQueue*类型的结构体指针,并且将该结构体指针的返回,该结构体指针就代表一个队列
    //然后通过操作该结构体指针指向的结构体中两个栈,来实现队列的一些操作。
    MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue));
    //将组成该队列的两个栈初始化。
    StackInit(&(queue->popstack));
    StackInit(&(queue->pushstack));
    return queue;
}

void myQueuePush(MyQueue* obj, int x) {
    assert(obj);
    StackPush(&(obj->pushstack),x);
}

int myQueuePop(MyQueue* obj) {
    assert(obj);
		//如果popstack栈为空,就将pushstack栈中的元素都入栈到popstack栈中。
    if(StackEmpty(&(obj->popstack)))
    {
        while(!StackEmpty(&(obj->pushstack)))
        {
					//将pushstack栈中的元素都进入到popstack栈中
            StackPush(&(obj->popstack),StackTop(&(obj->pushstack)));
						//然后将pushstack栈中的元素都出栈。
            StackPop(&(obj->pushstack));
        }
    }
			//此时popstack栈中的元素出栈的顺序和队列中元素出队的顺序一致。
			//此时popstack栈顶元素就是队列的队头元素
    int top = StackTop(&(obj->popstack));
    StackPop(&(obj->popstack));
    return top;
}

int myQueuePeek(MyQueue* obj) {
    assert(obj);
		//如果popstack栈为空,就将pushstack栈中的元素都入栈到popstack栈中。
    if(StackEmpty(&(obj->popstack)))
    {
        while(!StackEmpty(&(obj->pushstack)))
        {
					//将pushstack栈中的元素都进入到popstack栈中
            StackPush(&(obj->popstack),StackTop(&(obj->pushstack)));
						//然后将pushstack栈中的元素都出栈。
            StackPop(&(obj->pushstack));
        }
    }
		//此时popstack栈中的元素出栈的顺序和队列中元素出队的顺序一致。
    return StackTop(&(obj->popstack));
}

bool myQueueEmpty(MyQueue* obj) {
    assert(obj);
    return StackEmpty(&(obj->popstack))&&StackEmpty(&(obj->pushstack));
}

void myQueueFree(MyQueue* obj) {
    assert(obj);
    StackDestory(&(obj->pushstack));
    StackDestory(&(obj->popstack));

    free(obj);
}

你可能感兴趣的:(刷题,数据结构,算法)