用两个栈来实现队列

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

typedef int SltDatatype;
typedef struct Stack
{
	SltDatatype* a;//开辟栈的动态内存空间
	int top;//记录栈顶
	int capacity;//记录容量
}ST;

void STInit(ST* ps);//栈的初始化
void STDestroy(ST* ps);//释放
void STPush(ST* ps, SltDatatype x);//入栈
void STPop(ST* ps);//出栈
SltDatatype STTop(ps);//获取栈顶原数
int Size(ps);//求栈的长度
bool STEmpty(ST* ps);//空



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

void STPush(ST* ps,SltDatatype x)//入栈
{
	assert(ps);
	
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//因为初始化是capacity是0,所有这里需要,如果capacity是0的话,*2也是0,所有要在这里先给他一个值4
		//扩容
		SltDatatype * tmp= (SltDatatype*)realloc(ps->a, sizeof(SltDatatype) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps -> a = tmp;
		ps->capacity = newcapacity;

	}
	ps->a[ps->top] = x;
	ps->top++;
}

void STDestroy(ST* ps)//释放
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}
void STPop(ST* ps)//出栈
{
	assert(ps);
	assert(ps->top>0);//空
	ps->top--;

}



SltDatatype STTop(ST* ps)//获取栈顶原数
{

	assert(ps);
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}

int Size(ST* ps)//求栈的长度
{
	assert(ps);
	return ps->top;

}

bool STEmpty(ST* ps)//空
{
	assert(ps);
	return ps->top == 0;
}


//把两个栈包含在一个结构体中,然后通过这个结构体去操作两个栈,进而实现队列的功能
typedef struct {
    ST pushst;
    ST popst;

} MyQueue;


MyQueue* myQueueCreate() {//为结构体开辟一个指针,方便之后的访问操作
    MyQueue*obj=(MyQueue*)malloc(sizeof(MyQueue));
     STInit(&obj->pushst);//初始化两个栈
     STInit(&obj->popst);

		 return obj;
}

void myQueuePush(MyQueue* obj, int x) {//入队:就相当于往第一一个栈中压入数据
    STPush(&obj->pushst,x);

}



int myQueuePeek(MyQueue* obj) {//返回队列的头元素,就相当于返回第二个栈的栈顶元素
     if(STEmpty(&obj->popst))//如果第二个栈空了,那么就要在从第一个里面捣过来
    {
        while(!STEmpty(&obj->pushst))
        {
        STPush(&obj->popst,STTop(&obj->pushst));//因为是栈,所以每捣一次都是捣的栈顶元素
        STPop(&obj->pushst);//并且既然捣过去了,那就要把第一个里面的删了;
        }
    }
    return STTop(&obj->popst);

}

int myQueuePop(MyQueue* obj) {
   int val= myQueuePeek(obj);//保存队列的头元素
        STPop(&obj->popst);//从队列的开头移除这个元素:就相当于删除第二个栈的栈顶元素
        return val;

   
}

bool myQueueEmpty(MyQueue* obj) {
    return STEmpty(&obj->popst)&&STEmpty(&obj->pushst);//两个栈都是空,那么模拟出来的队列就是空
}

void myQueueFree(MyQueue* obj) {
    STDestroy(&obj->popst);//先释放两个栈
    STDestroy(&obj->pushst);
    free(obj);//再释放储存两个栈变量的结构体空间
}

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