本人在写这道题的时候煞费苦心,特来将解题思路和代码分享给各位已备不时之需。
题目:
解题思路:
首先,我们要了解这道题的意义。这道题并不具有实际中的作用,只具有教学意义。以后面试之类的可能会考,但绝对不适用c语言,因为成本太高(在做提前还要先写一个队列),而这道题主要考察的是对队列中函数的调用来实现栈的基本功能,比如尾插和尾删,我认为这道题的难点就在尾删,需要合理运用两个队列。主要讲下尾插,尾删。
代码:
typedef int QDataType;
typedef struct QListNode
{
struct QListNode* next;
QDataType data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* front;
QNode* rear;
int size;
}Queue;
// 初始化队列
void QueueInit(Queue* q)
{
assert(q);
q->front =q->rear=NULL;
q->size = 0;
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data)
{
assert(q);
QNode* a = (QNode*)malloc(sizeof(QNode));
if (a == NULL)
{
perror("malloc fail");
return;
}
a->next = NULL;
a->data = data;
if (q->rear == NULL)
{
q->front = q->rear = a;
}
else
{
q->rear->next = a;
q->rear = a;
}
q->size++;
}
// 队头出队列
void QueuePop(Queue* q)
{
assert(q);
assert(q->size !=0);
if (q->front->next == NULL)
{
free(q->front);
q->front = q->rear = NULL;
}
else
{
QNode* cur = q->front->next;
free(q->front);
q->front = cur;
}
q->size--;
}
// 获取队列头部元素
QDataType QueueFront(Queue* q)
{
assert(q);
assert(q->size);
return q->front->data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q)
{
assert(q);
assert(q->size);
return q->rear->data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q)
{
assert(q);
assert(q->size);
return q->size;
}
bool QueueEmpty(Queue* q)
{
assert(q);
// return p->size == 0;
return !q->size;
}
// 销毁队列
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;
q->size = 0;
}
typedef struct
{
Queue q1;
Queue q2;
} MyStack;//为了避免使用二级指针,我们将队列放进结构体中
MyStack* myStackCreate()
{
MyStack* temp = (MyStack*)malloc(sizeof(MyStack));//局部变量出了函数就会自动销毁,所以要动态申请内存空间
QueueInit(&temp->q1);
QueueInit(&temp->q2);
return temp;
}
void myStackPush(MyStack* obj, int x)
{
assert(obj);
if (!QueueEmpty(&obj->q1))
{
QueuePush(&obj->q1, x);
}
else
{
QueuePush(&obj->q2, x);
}
}
int myStackPop(MyStack* obj)
{
//出栈是这道题目的关键也是难点
Queue* empty = &obj->q1;
Queue* nonempty = &obj->q2;
if (!QueueEmpty(&obj->q1))//用假设法让题目变得更加简单
{
empty = &obj->q2;
nonempty = &obj->q1;
}
while (QueueSize(nonempty) > 1)
{
QueuePush(empty, QueueFront(nonempty));
QueuePop(nonempty);
}
int n = QueueFront(nonempty);
QueuePop(nonempty);
return n;
}
int myStackTop(MyStack* obj)
{
if (!QueueEmpty(&obj->q1))
{
return QueueBack(&obj->q1);
}
else
{
return QueueBack(&obj->q2);
}
return 0;
}
bool myStackEmpty(MyStack* obj)
{
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj)
{
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
}