用栈实现队列
- 解析
根据栈与队列的特性我们用两个栈来模拟实现队列。首先s1用来模拟入队列,s2用来模拟出队列。入队列时直接将元素放入s1中,出队列时,如果s2为空,那么将s1中的元素push到s2中此时元素是逆序的s2的栈顶就是队头,并删除s2栈顶,若s2不为空则直接删除s2栈顶。获取队头与出队列操作相似,将删除操作改为返回操作即可。
2.代码实现
栈的基本操作
typedef int STDataType;
typedef struct Stack
{
STDataType* array; // 栈顶
int _capacity; // 容量
int size;//栈顶
}Stack;
void CheckCapacity(Stack* ps) {
assert(ps);
if (ps->size >=ps->_capacity) {
ps->_capacity *= 2;
ps->array = (STDataType*)realloc(ps->array, ps->_capacity * sizeof(STDataType));
}
}
void StackInit(Stack* ps) {
assert(ps);
ps->array = (STDataType*)malloc(sizeof(STDataType) * 4);
if (ps->array == NULL) {
assert(0);
}
ps->_capacity = 4;
ps->size = 0;
}
// 入栈
void StackPush(Stack* ps, STDataType data) {
CheckCapacity(ps);//检查容量够不够
ps->array[ps->size] = data;
ps->size++;
}
// 出栈
void StackPop(Stack* ps) {
assert(ps->size);
ps->size--;
}
// 获取栈顶元素
STDataType StackTop(Stack* ps) {
assert(!StackEmpty(ps));
return ps->array[ps->size-1];
}
// 获取栈中有效元素个数
int StackSize(Stack* ps) {
assert(ps);
return ps->size;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* ps) {
assert(ps);
return ps->size == 0;
}
// 销毁栈
void StackDestroy(Stack* ps) {
assert(ps);
if (ps->array) {
free(ps->array);
ps->array = NULL;
ps->size = 0;
ps->_capacity = 0;
}
}
模拟实现部分
typedef struct {
Stack s1;
Stack s2;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* mq=(MyQueue*)malloc(sizeof(MyQueue));
if(mq==NULL){
return NULL;
}
StackInit(&(mq->s1));
StackInit(&(mq->s2));
return mq;
}
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->s1,x);
}
int myQueuePop(MyQueue* obj) {
if(StackEmpty(&obj->s2)){
while(!StackEmpty(&obj->s1)){
StackPush(&obj->s2,StackTop(&obj->s1));
StackPop(&obj->s1);
}
}
int ret =0;
ret=StackTop(&obj->s2);
StackPop(&obj->s2);
return ret;
}
int myQueuePeek(MyQueue* obj) {
if(StackEmpty(&obj->s2)){
while(!StackEmpty(&obj->s1)){
StackPush(&obj->s2,StackTop(&obj->s1));
StackPop(&obj->s1);
}
}
return StackTop(&obj->s2);
}
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->s1)&&StackEmpty(&obj->s2);
}
void myQueueFree(MyQueue* obj) {
if(obj!=NULL){
StackDestroy(&obj->s1);
StackDestroy(&obj->s2);
free(obj);
}
}
用队列实现栈
1.解析
与之前类似,用两个队列来实现栈,入栈时,哪个队列不空,让元素入哪个队列,出栈时,哪个队列不空将其前N-1个元素挪到另一个队列中,它剩下的那个一个元素出队列,获取栈顶元素时,哪个队列不空,返回队尾就可以。
2.代码实现
队列的基本操作
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=NULL;
q->rear=NULL;
q->front = q->rear;
q->size = 0;
}
QNode* BuyNode(QDataType data) {
QNode* newNode = (QNode*)malloc(sizeof(QNode));
newNode->data = data;
newNode->next= NULL;
return newNode;
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data) {
assert(q);
QNode* newNode = BuyNode(data);
if (q->front == NULL) {
q->front = newNode;
}
else {
q->rear->next = newNode;
}
q->rear = newNode;
q->size++;
}
// 队尾出队列
void QueuePop(Queue* q) {
if (QueueEmpty(&q)) {
return;
}
else {
QNode* delNode=q->front;
q->front=delNode->next;
free(delNode);
if(q->front==NULL){
q->rear=NULL;
}
}
q->size--;
}
// 获取队列头部元素
QDataType QueueFront(Queue* q) {
assert(!QueueEmpty(&q));
return q->front->data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q) {
assert(!QueueEmpty(&q));
return q->rear->data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q) {
assert(q);
return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q) {
assert(q);
return NULL==QueueFront(&q);
}
// 销毁队列
void QueueDestroy(Queue* q) {
assert(q);
QNode* cur = q->front;
while (cur) {
q->front = cur->next;
free(cur);
cur = q->front;
}
q->rear=NULL;
q->size=0;
}
模拟实现
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* ms=(MyStack*)malloc(sizeof(MyStack));
if(ms==0){
return NULL;
}
QueueInit(&ms->q1);
QueueInit(&ms->q2);
return ms;
}
void myStackPush(MyStack* obj, int x) {
if(QueueEmpty(&obj->q1)){
QueuePush(&obj->q2,x);
}
else{
QueuePush(&obj->q1,x);
}
}
int myStackPop(MyStack* obj) {
int tmp=0;
if(QueueEmpty(&obj->q1)){
while(QueueSize(&obj->q2)>0){
QueuePush(&obj->q1,QueueFront(&obj->q2));
QueuePop(&obj->q2);
}
tmp=QueueFront(&obj->q2);
QueuePop(&obj->q2);
}else{
while(QueueSize(&obj->q1)>0){
QueuePush(&obj->q2,QueueFront(&obj->q1));
QueuePop(&obj->q1);
}
tmp=QueueFront(&obj->q1);
QueuePop(&obj->q1);
}
return tmp;
}
int myStackTop(MyStack* obj) {
if(QueueEmpty(&obj->q1)){
return QueueFront(&obj->q2);
}else{
return QueueFront(&obj->q1);
}
}
bool myStackEmpty(MyStack* obj) {
if(QueueSize(&obj->q1)==0&&QueueSize(&obj->q2)==0){
return true;
}else{
return false;
}
}
void myStackFree(MyStack* obj) {
if(obj!=NULL){
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
}
}