目录
1.1实现原理:在前文中我们已经实现了队列和栈,但是如何去用对列的功能实现栈呢?
1.用队列实现栈
1.1实现原理:在前文中我们已经实现了队列和栈,但是如何去用对列的功能实现栈呢?
对列是先进先出,栈是先进后出,所以我们不妨开辟两块空间,来回倒腾。
我们用对列的先进先出存放数据,让后我们再利用栈先进后出的性质,先把前面的数据移到新区,然后删去最后一个数据。我们在这用C语言实现。
1.2代码实现
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int QdateType;
typedef struct QueueNode// 节点
{
QdateType data;
struct QueueNode* next;
}QNode;
typedef struct Queue
{
int size;
QNode* head;
QNode* tail;
}Queue;
//初始化
void QueueInit(Queue* pd);
//销毁
void QueueDestroy(Queue* pd);
// 判空
int QueueEmpty(Queue* pd);
//入列
void QueuePush(Queue* pd, QdateType x);
//返回队尾
void QueueBack(Queue* pd);
//返回队首
void QueueFront(Queue* pd);
//返回个数
int QueueSize(Queue* pd);
//初始化
void QueueInit(Queue* pd)
{
assert(pd);
pd->head = pd->tail = NULL;
pd->size = 0;
}
//销毁
void QueueDestroy(Queue* pd)
{
assert(pd);
QNode* cur = pd->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pd->head = pd->tail = NULL;
}
//判空
int QueueEmpty(Queue* pd)
{
if (pd->head == NULL)
{
return 1;
}
else
return 0;
}
//返回长度
int QueueSize(Queue* pd)
{
return pd->size;
}
//入列
void QueuePush(Queue* pd, QdateType x)
{
assert(pd);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
printf("malloc:falue");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
//一个没有就进行插入
if (pd->tail == NULL)
{
pd->head = pd->tail = newnode;
}
else
{
pd->tail->next = newnode;
pd->tail = newnode;
}
}
//出列
void QueuePop(Queue* pd)
{
assert(pd);
assert(!QueueEmpty(pd));
if (pd->head->next == NULL)
{
free(pd->head);
pd->head = pd->tail = NULL;
}
else
{
QNode* next = pd->head->next; //保存下一个节点地址,防止找不到
free(pd->head);
pd->head = next;
}
}
//返回队首
void QueueFront(Queue* pd)
{
assert(pd);
assert(!QueueEmpty(pd));
return pd->head->data;
}
//返回队尾
void QueueBack(Queue* pd)
{
assert(pd);
assert(!QueueEmpty(pd));
return pd->tail->data;
}
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)
{
}
//返回栈顶值
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) {
if (QueueEmpty(&obj->q1))
QueueDestory(&obj->q2);
else
QueueDestory(&obj->q1);
}
这其中就自己写的值在两块空间互换那个有点难。
2栈实现队列
2.1实现思路
也就是用栈实现先进先出。,仿照上面创建两个对列,那我们再创建两个栈。
2.2代码实现
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int STDataType;
typedef struct Stack
{
STDataType* data;//数据
int top;//栈顶
int capacity;//容量
}Stack;
// 初始化栈
void StackInit(Stack* ps)
{
assert(ps);
ps->capacity = 0;
ps->data = NULL;
ps->top = 0;
}
// 入栈
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
if (ps->top == ps->capacity)//判断容量
{
int newcapacity = (ps->capacity == 0 ? 4 : 2 * ps->capacity);
STDataType* tmp = realloc(ps->data, sizeof(STDataType) * newcapacity);//扩容
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->capacity = newcapacity;
ps->data = tmp;
}
ps->data[ps->top] = data;//压入数据
ps->top++;
}
// 出栈
void StackPop(Stack* ps)
{
assert(ps);
if (ps->top == 0)return NULL;
ps->top--;
}
// 获取栈顶元素
STDataType StackTop(Stack* ps)
{
assert(ps);
if (ps->top == 0)return NULL;
return ps->data[ps->top - 1];//top位置是压入数据的位置,所以栈顶元素也就是它前一个元素
}
// 获取栈中有效元素个数
int StackSize(Stack* ps)
{
return ps->top;
}
// 销毁栈
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->data);
ps->data = NULL;
ps->top = 0;
ps->capacity = 0;
}
int StackEmpty(Stack* ps)
{
if (ps->top == 0)return 1;
else return 0;
}
typedef struct {
Stack PushST;
Stack PopST;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&(obj->PushST));
StackInit(&(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));
}
}
STDataType 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));
}
}
return StackTop(&(obj->PopST));
}
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&(obj->PushST)) && StackEmpty(&(obj->PopST));
}
void myQueueFree(MyQueue* obj) {
StackDestroy(&(obj->PopST));
StackDestroy(&(obj->PushST));
free(obj);
}
这个栈实现对列的精华是push栈中的数据往pop栈中转移,转移过程中一定注意两者情况:1.pop栈中没有数据,那可以直接转栈,2.是pop栈中有数据,那必须是先把pop栈中数据转移出来在移动数据。
用C语言实现过程难免有一些冗余,有问题可以私信我。