225. 用队列实现栈(C实现)

题目

题目链接:225. 用队列实现栈

225. 用队列实现栈(C实现)_第1张图片


思路

用两个队列来模拟实现栈的操作!
入栈操作:即给任意一个空的队列入队即完成入栈操作;
出栈操作:先把有数据的队列q1的值出队到另一个队列q2,当q1剩余一个数据时候,那么就出队最后一个数据,表示出栈!


由于C语言没有提供队列的数据结构,所以需要自己实现一个队列;
该队列:队尾入队,队头出队,保持先进先出即可!


c代码实现

typedef int QDataType;

typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* head;
	QueueNode* tail;
}Queue;


void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = NULL;
	pq->tail = NULL;
}
//释放队列的所有结点
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->head;

	while (cur)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
}
//入队,队尾入队
void QueuePush(Queue* pq,QDataType x)
{
	assert(pq);
	QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
	newNode->data = x;
	newNode->next = NULL;

	//插入的数据为第一个结点
	if (pq->head == NULL)
	{
		pq->head = pq->tail = newNode;
	}
	else //不是第一个结点
	{
		pq->tail->next = newNode;
		pq->tail = newNode;
	}
}
//出队,对头出队
void QueuePop(Queue* pq)
{
	assert(pq);
	
	assert(pq->head); //队列为空不可以删
	//队列不为空,删
	QueueNode* next = pq->head->next;
	free(pq->head);
	pq->head = next;
	//单独出来还剩最后一个结点
	//tail 和 head 都执行最后一个结点,
	//此时要置空tail
	//防止野指针
	if (pq->head == NULL)
	{
		pq->tail = NULL;
	}

}
//判断队列是否为空
bool QueueIsEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;
}
//获取队尾数据
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->tail->data;
}

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head != NULL); //空队列
	return pq->head->data;
}
int QueueSize(Queue* pq)
{
	assert(pq);

	QueueNode* cur = pq->head;
	int count = 0;
	while (cur)
	{
		cur = cur->next;
		count++;
	}
	return count;

}
typedef struct {
    Queue q1;
    Queue q2;
} MyStack;

//用两个队列模拟栈,其实就是初始化两个队列就可以得到一个栈
MyStack* myStackCreate() {
    MyStack* st = (MyStack*)malloc(sizeof(MyStack));
    QueueInit(&(st->q1));
    QueueInit(&(st->q2));
    return st;
}
//栈的入栈和队列一样
//往不为空的队列入队,达到模拟栈的入栈的效果
//如果都为空,随便入一个就行!
void myStackPush(MyStack* obj, int x) {
    if(!QueueIsEmpty(&obj->q1))
    {
        QueuePush(&obj->q1,x);
    }
    else
    {
        QueuePush(&obj->q2,x);
    }
}
//往空的队列里面入队,剩下最后的一个元素就出队,达到模拟栈出队的效果
int myStackPop(MyStack* obj) {
    //由于不知道哪个是空的队列,所以先假设
    Queue* emptyQ =&obj->q1 ;
    Queue* NoEmptyQ = &obj->q2;

    if(!QueueIsEmpty(&obj->q1))
    {
        NoEmptyQ = &obj->q1;
        emptyQ = &obj->q2;
    }

    //把非空的队列出队到空的队列,剩最后一个元素即可

    while(QueueSize(NoEmptyQ) > 1)
    {
        QueuePush(emptyQ,QueueFront(NoEmptyQ));
        QueuePop(NoEmptyQ);
    }
    //退出上面的循环,就非空队列剩下一个元素,出队即模拟栈的出栈了
    int top = QueueFront(NoEmptyQ);
    QueuePop(NoEmptyQ);
    return top;
}

int myStackTop(MyStack* obj) {
    if(!QueueIsEmpty(&obj->q1))
    {
        return QueueBack(&obj->q1);
    }
    else
    {
        return QueueBack(&obj->q2);
    }
}

bool myStackEmpty(MyStack* obj) {
    return QueueIsEmpty(&obj->q1) && QueueIsEmpty(&obj->q2);
}

void myStackFree(MyStack* obj) {
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    free(obj);

}

/**
 * Your MyStack struct will be instantiated and called as such:
 * MyStack* obj = myStackCreate();
 * myStackPush(obj, x);
 
 * int param_2 = myStackPop(obj);
 
 * int param_3 = myStackTop(obj);
 
 * bool param_4 = myStackEmpty(obj);
 
 * myStackFree(obj);
*/

你可能感兴趣的:(Leetcode,c语言,链表,数据结构)