用队列实现栈(C语言实现)

上一章实现了用栈来实现队列,这一次我们试试用队列来实现栈。

因为栈的特性是先进后出,队列是先进先出
所以我们可以想到用两个队列,一个空队列,一个放数据,当我们入队的时候将数据直接放入非空队列,出队的时候将非空队列中除队尾外的所有元素放到空队列中,再出队尾即可。
如下图
如数据1,2,3,4
在这里插入图片描述
全部入队
在这里插入图片描述
模拟出栈
在这里插入图片描述
先将除队尾全部放到原来的空队列中
在这里插入图片描述
再进行出队,即可实现栈的特性先进后出

下面开始代码实现,

数据结构

typedef int DataType;
typedef struct QListNode
{
	struct QListNode* next;
	DataType data;
}QNode;

typedef struct Queue
{
	QNode* front;
	QNode* rear;
}Queue;

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

栈的实现部分就不再这里放了,之前几章有

初始化栈



MyStack* myStackCreate() 
{
    MyStack* stack = (MyStack*)malloc(sizeof(MyStack));

    QueueInit(&stack->q1);
    QueueInit(&stack->q2);

    return stack;
}

入栈

void myStackPush(MyStack* obj, int x) 
{
    if(0 != QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q2, x);
    }
    else
    {
        QueuePush(&obj->q1, x);
    }
}

将数据放入非空队列中

出栈


int myStackPop(MyStack* obj) 
{
    Queue* emptyq = &obj->q2, *noemptyq = &obj->q1;
    DataType target;
    if(0 != QueueEmpty(&obj->q1))
    {
        emptyq = &obj->q1;
        noemptyq = &obj->q2;
    }

    while(QueueSize(noemptyq) > 1)
    {
        QueuePush(emptyq, QueueFront(noemptyq));
        QueuePop(noemptyq);
    }

    target = QueueFront(noemptyq);
    QueuePop(noemptyq);

    return target;        
}

将非空队列除最后一个元素外的全部元素放到空队列中

获取栈顶

int myStackTop(MyStack* obj) 
{
    Queue* noemptyq = &obj->q1;
    if(0 != QueueEmpty(&obj->q1))
    {
        noemptyq = &obj->q2;
    }
    return QueueBack(noemptyq);
}

返回非空队列的队尾即最后一个元素,即为栈顶

判断栈是否为空

bool myStackEmpty(MyStack* obj) 
{
    if(QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2))
        return true;
    else
        return false;
}

当两个队列全部为空时栈为空

销毁栈


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

这样我们就实现了用队列来实现栈

完整代码

typedef int DataType;
typedef struct QListNode
{
	struct QListNode* next;
	DataType data;
}QNode;

typedef struct Queue
{
	QNode* front;
	QNode* rear;
}Queue;

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


void QueueInit(Queue* q)
{
	q->front = q->rear = NULL;
}

DataType QueueFront(Queue* q)
{
	if(q->front != NULL)
	    return q->front->data;
    else    
        return NULL;
}

DataType QueueBack(Queue* q)
{
	if(q->rear != NULL)
	    return q->rear->data;
    else    
        return NULL;
}

int QueueEmpty(Queue* q)
{
	return q->front ? 0 : 1;
}


int QueueSize(Queue* q)
{
	assert(q);

	QNode* cur = q->front;
	int count = 0;

	while (cur)
	{
		count++;
		cur = cur->next;
	}

	return count;
}

void QueuePush(Queue* q, DataType data)
{
	assert(q);

	QNode* node = (QNode*)malloc(sizeof(QNode));
	node->data = data;
	node->next = NULL;

	if (q->rear)
	{
		q->rear->next = node;
		q->rear = node;
	}
	else
	{
		q->front = q->rear = node;
	}

} 

void QueuePop(Queue* q)
{
	assert(q);

	if (NULL == q->front->next)
	{
		free(q->front);
		q->front = q->rear = NULL;
	}
	else
	{
		QNode* next = q->front->next;
		free(q->front);
		q->front = next;
	}
}

void QueueDestroy(Queue* q)
{
	assert(q);

	QNode* cur = q->front;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	q->front = q->rear = NULL;
}

MyStack* myStackCreate() 
{
    MyStack* stack = (MyStack*)malloc(sizeof(MyStack));

    QueueInit(&stack->q1);
    QueueInit(&stack->q2);

    return stack;
}

void myStackPush(MyStack* obj, int x) 
{
    if(0 != QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q2, x);
    }
    else
    {
        QueuePush(&obj->q1, x);
    }
}

int myStackPop(MyStack* obj) 
{
    Queue* emptyq = &obj->q2, *noemptyq = &obj->q1;
    DataType target;
    if(0 != QueueEmpty(&obj->q1))
    {
        emptyq = &obj->q1;
        noemptyq = &obj->q2;
    }

    while(QueueSize(noemptyq) > 1)
    {
        QueuePush(emptyq, QueueFront(noemptyq));
        QueuePop(noemptyq);
    }

    target = QueueFront(noemptyq);
    QueuePop(noemptyq);

    return target;        
}

int myStackTop(MyStack* obj) 
{
    Queue* noemptyq = &obj->q1;
    if(0 != QueueEmpty(&obj->q1))
    {
        noemptyq = &obj->q2;
    }
    return QueueBack(noemptyq);
}

bool myStackEmpty(MyStack* obj) 
{
    if(QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2))
        return true;
    else
        return false;
}

void myStackFree(MyStack* obj) 
{
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    free(obj);
    obj = NULL;
}
发布了60 篇原创文章 · 获赞 78 · 访问量 6322

猜你喜欢

转载自blog.csdn.net/qq_35423154/article/details/104430129