目录
用栈实现队列
思路:定义两个栈,一个专门用来进栈 PushSt,一个专门用来出栈PopSt,当队列元素需要出队且PopSt为空时,从PushSt中把所有数据导入到PopSt中,在PopSt中使用出栈的方式,即弹出栈顶元素的方式出掉队列中队头的元素,如果PopSt不为空,直接让它出栈。当执行完出队操作而执行入队操作时,不需要再从PopSt中再导回数据到PushSt中。访问队列的头部元素,在PopSt中取栈顶元素;访问队列的尾部元素,在PushSt中访问栈顶元素。
typedef int DataType;
typedef struct Stack {
DataType* a;
int top;
int capacity;
}Stack;
void InitStack(Stack* ps) {
ps->a = NULL;
ps->top = ps->capacity = 0;
}
void StackDestroy(Stack* ps) {
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
//进栈
void StackPush(Stack* ps, DataType x) {
assert(ps);
if (ps->capacity == ps->top) {
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
DataType* tmp = (DataType*)realloc(ps->a, sizeof(DataType) * newcapacity);
if (tmp == NULL) {
printf("realloc fail\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
//判断栈是否为空
bool StackEmpty(Stack* ps) {
assert(ps);
return ps->top == 0;
}
//出栈
void StackPop(Stack* ps) {
assert(ps && !StackEmpty(ps));
ps->top--;
}
//取栈顶元素
DataType StackTop(Stack* ps) {
assert(ps && !StackEmpty(ps));
return ps->a[ps->top - 1];
}
//栈元素个数
int StackSize(Stack* ps) {
assert(ps);
return ps->top;
}
typedef struct {
Stack PushSt;
Stack PopSt;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
if(obj==NULL){
printf("malloc fail\n");
exit(-1);
}
InitStack(&obj->PushSt);
InitStack(&obj->PopSt);
return obj;
}
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->PushSt,x);
}
//从队列的开头移除并返回元素
int myQueuePop(MyQueue* obj) {
if(StackEmpty(&obj->PopSt)){
while(!StackEmpty(&obj->PushSt)){
StackPush(&obj->PopSt,StackTop(&obj->PushSt));
StackPop(&obj->PushSt);
}
}
int front=StackTop(&obj->PopSt);
StackPop(&obj->PopSt);
return front;
}
//返回队列开头元素
int myQueuePeek(MyQueue* obj) {
if(StackEmpty(&obj->PopSt)){
while(!StackEmpty(&obj->PushSt)){
StackPush(&obj->PopSt,StackTop(&obj->PushSt));
StackPop(&obj->PushSt);
}
}
int front=StackTop(&obj->PopSt);
return front;
}
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->PushSt) && StackEmpty(&obj->PopSt);
}
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->PopSt);
StackDestroy(&obj->PushSt);
free(obj);
}
用队列实现栈
思路:定义两个队列q1和q2,若要进行出栈操作,先判断两个队列哪个为空,哪个非空,将非空队列上的数据移出到只剩一个元素,一边出元素,一边将出的元素导到空的队列中,非空队列上最后一个元素就是出栈元素,且符合队列队头出队的原则,此时可以移出元素。当进行入队操作时,选择非空的队列入元素。
typedef int QDataType;
// 链式结构:表示队列
typedef struct QListNode
{
struct QListNode* _next;
QDataType _data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* _front;
QNode* _rear;
}Queue;
void QueueInit(Queue* pq);
void QueuePush(Queue* pq, QDataType data);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);
void QueueDestroy(Queue* pq);
void QueueInit(Queue* pq) {
assert(pq);
pq->_front = pq->_rear = NULL;
}
// 队尾入队列
void QueuePush(Queue* pq, QDataType data) {
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL) {
printf("malloc fail\n");
return;
}
newnode->_data = data;
newnode->_next = NULL;
if (pq->_front == NULL) {
pq->_front = pq->_rear = newnode;
}
else {
pq->_rear->_next = newnode;
pq->_rear = newnode;
}
}
// 队头出队列
void QueuePop(Queue* pq) {
assert(pq);
if (QueueEmpty(pq)) {
return;
}
//只剩一个元素
if (pq->_front->_next == NULL) {
free(pq->_front);
pq->_front = pq->_rear = NULL;
}
//多于一个元素
else {
QNode* next = pq->_front->_next;
free(pq->_front);
pq->_front = next;
}
}
// 获取队列头部元素
QDataType QueueFront(Queue* pq) {
assert(pq && !QueueEmpty(pq));
return pq->_front->_data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* pq) {
assert(pq && !QueueEmpty(pq));
return pq->_rear->_data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* pq) {
assert(pq);
QNode* cur = pq->_front;
int size = 0;
while (cur) {
size++;
cur = cur->_next;
}
return size;
}
bool QueueEmpty(Queue* pq) {
assert(pq);
return pq->_front==NULL;
}
// 销毁队列
void QueueDestroy(Queue* pq) {
assert(pq);
QNode* cur = pq->_front;
while (cur) {
QNode* next = cur->_next;
free(cur);
cur = next;
}
pq->_front=pq->_rear=NULL;
}
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* obj=(MyStack*)malloc(sizeof(MyStack));
QueueInit(&obj->q1);
QueueInit(&obj->q2);
return obj;
}
void myStackPush(MyStack* obj, int x) {
if(QueueEmpty(&obj->q1)){
QueuePush(&obj->q2,x);
}
else{
QueuePush(&obj->q1,x);
}
}
int myStackPop(MyStack* obj) {
Queue* EmptyQ=&obj->q1;
Queue* NonEmptyQ=&obj->q2;
if(!QueueEmpty(&obj->q1)){
EmptyQ=&obj->q2;
NonEmptyQ=&obj->q1;
}
while(QueueSize(NonEmptyQ) > 1){
QueuePush(EmptyQ,QueueFront(NonEmptyQ));
QueuePop(NonEmptyQ);
}
int top=QueueFront(NonEmptyQ);
QueuePop(NonEmptyQ);
return top;
}
int myStackTop(MyStack* obj) {
if(QueueEmpty(&obj->q1)){
return QueueBack(&obj->q2);
}
else{
return QueueBack(&obj->q1);
}
}
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
}