目录
栈的实现
队列的实现
相互实现
既然栈和队列的基本结构和规则都有了,那么,一个成熟的程序员要学会变着花样玩。
首先,上两道题目了解一下:
用队列实现栈
破防时刻
既然要用两个队列去实现栈,那么很显然,新栈的结构体成员就是两个队列,那么问题来了,我们是用结构体呢?还是用结构体指针呢?
这个问题啊,当然是只有经历了才知道,本小白通过自己的惨痛教训告诫大家,还是尽量用结构体成员吧。😭😭😭
那用指针有什么问题呢?
如果你不幸用了指针(啊其实是在说我自己),那么初始化的时候就不能调用队列的初始化函数,否则结构体里面的就是两个随机值,从而导致找不到q1的实体,那么你就需要直接将q1,q2置为空,这一置空,你就需要在bush和pop函数中对队列进行实体化,而且判断队列为空的函数也需换成obj->q1==NULL,在后续函数实现中也需要多很多判断,有些内容甚至需要探到链表的一层去完成。总的来说别用指针就对了。当然,两种实现方法都贴出来让大家鉴赏一下。
栈结构体用队列指针
对列结构:
typedef int QDataType;
typedef struct QListNode
{
struct QListNode* _next;
QDataType _data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* _head;
QNode* _tail;
}Queue;
void QueueInit(Queue* q)
{
assert(q);
q->_head = NULL;
q->_tail = NULL;
}
void QueuePush(Queue* q, QDataType data)
{
assert(q);
QNode* newNode = (QNode*)malloc(sizeof(QNode));
assert(newNode);
newNode->_next = NULL;
newNode->_data = data;
if (q->_tail == NULL)
{
assert(q->_head == NULL);
q->_head = q->_tail = newNode;
}
else
{
q->_tail->_next = newNode;
q->_tail = newNode;
}
}
void QueuePop(Queue* q)
{
assert(q);
assert(q->_head && q->_tail);
if (q->_head->_next == NULL)
{
free(q->_head);
q->_head = q->_tail = NULL;
}
else
{
QNode* next = q->_head->_next;
free(q->_head);
q->_head = next;
}
}
QDataType QueueFront(Queue* q)
{
assert(q);
assert(q->_head);
return q->_head->_data;
}
QDataType QueueBack(Queue* q)
{
assert(q);
assert(q->_tail);
return q->_tail->_data;
}
int QueueSize(Queue* q)
{
assert(q);
QNode* cur = q->_head;
size_t size = 0;
while (cur)
{
size++;
cur = cur->_next;
}
return size;
}
int QueueEmpty(Queue* q)
{
assert(q);
return q->_head == NULL;
}
void QueueDestroy(Queue* q)
{
assert(q);
QNode* next = NULL;
QNode* cur = q->_head;
while (cur)
{
next = cur->_next;
free(cur);
cur = next;
}
q->_head = NULL;
q->_tail = NULL;
}
用队列实现栈:
typedef struct
{
Queue* q1;
Queue* q2;
} MyStack;
MyStack* myStackCreate()
{
MyStack* st = (MyStack*)malloc(sizeof(MyStack));
assert(st);
st->q1 = NULL;
st->q2 = NULL;
return st;
}
void myStackPush(MyStack* obj, int x)
{
assert(obj);
if (obj->q1)
{
QueuePush(obj->q1, x);
}
else if(obj->q2)
{
QueuePush(obj->q2, x);
}
else
{
Queue* q1 =(Queue*) malloc(sizeof(Queue));
assert(q1);
obj->q1 = q1;
QueueInit(obj->q1);
QueuePush(obj->q1,x);
}
}
int myStackPop(MyStack* obj)
{
Queue* empty = NULL;
Queue* noEmpty = NULL;
if (obj->q1)
{
if (obj->q1->_head == obj->q1->_tail)
{
QDataType ret = QueueFront(obj->q1);
QueueDestroy(obj->q1);
obj->q1 = NULL;
return ret;
}
noEmpty = obj->q1;
obj->q1 = NULL;
empty = obj->q2 = (Queue*)malloc(sizeof(Queue));
assert(empty);
QueueInit(obj->q2);
}
else if (obj->q2)
{
if (obj->q2->_head == obj->q2->_tail)
{
QDataType ret = QueueFront(obj->q2);
QueueDestroy(obj->q2);
obj->q2 = NULL;
return ret;
}
noEmpty = obj->q2;
obj->q2 = NULL;
empty = obj->q1 = (Queue*)malloc(sizeof(Queue));
assert(empty);
QueueInit(obj->q1);
}
else
{
return 0;
}
QDataType top = QueueBack(noEmpty);
QNode* cur = noEmpty->_head;
while (cur != noEmpty->_tail)
{
QueuePush(empty, cur->_data);
cur = cur->_next;
}
QueueDestroy(noEmpty);
return top;
}
int myStackTop(MyStack* obj)
{
Queue* empty = NULL;
Queue* noEmpty = NULL;
if (obj->q1)
{
noEmpty = obj->q1;
empty = obj->q2;
}
else if (obj->q2)
{
noEmpty = obj->q2;
empty = obj->q1;
}
else
{
return -1;
}
return QueueBack(noEmpty);
}
bool myStackEmpty(MyStack* obj)
{
if (obj->q1|| obj->q2)
{
return 0;
}
else
{
return 1;
}
}
void myStackFree(MyStack* obj)
{
if(obj->q1)
QueueDestroy(obj->q1);
if(obj->q2)
QueueDestroy(obj->q2);
free(obj);
}
int main()
{
MyStack* st;
st = myStackCreate();
myStackPush(st, 1);
myStackPop(st);
myStackPush(st, 2);
printf("%d", myStackTop(st));
myStackFree(st);
}
测试:
int main()
{
MyStack* st;
st = myStackCreate();
myStackPush(st, 1);
myStackPop(st);
myStackPush(st, 2);
printf("%d", myStackTop(st));
myStackFree(st);
}
栈结构体用队列实体
队列结构与上相同,可以复用
用队列实现栈
typedef struct
{
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate()
{
MyStack* st = (MyStack*)malloc(sizeof(MyStack));
assert(st);
QueueInit(&st->q1);
QueueInit(&st->q2);
return st;
}
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)
{
assert(obj);
Queue* empty = &obj->q1;
Queue* noEmpty = &obj->q2;
if (!QueueEmpty(&obj->q1))
{
noEmpty = &obj->q1;
empty = &obj->q2;
}
while (QueueSize(noEmpty)>1)
{
QueuePush(empty, QueueFront(noEmpty));
QueuePop(noEmpty);
}
QDataType top = QueueBack(noEmpty);
QueuePop(noEmpty);
return top;
}
int myStackTop(MyStack* obj)
{
assert(obj);
if (!QueueEmpty(&obj->q1))
{
return QueueBack(&obj->q1);
}
else
{
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj)
{
assert(obj);
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj)
{
assert(obj);
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
}
测试函数:
int main()
{
MyStack* st;
st = myStackCreate();
myStackPush(st, 1);
myStackPop(st);
myStackPush(st, 2);
printf("%d", myStackTop(st));
myStackFree(st);
}
用栈实现队列
有了前车之鉴,我自然是没有在这里用指针实现了,如果哪个宝宝感兴趣,我也就推荐你多试试哈哈哈哈哈。
栈的结构
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;//栈顶位置
int capacity;//容量
}ST;
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->capacity = 0;
ps->top = -1;
}
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->capacity = 0;
ps->top = -1;
}
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top + 1 == ps->capacity)
{
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
ps->a = (STDataType*)realloc(ps->a, newCapacity * sizeof(STDataType));
assert(ps->a);
if (ps->a == NULL)
{
printf("realloc fail\n");
exit(-1);
}
}
ps->top++;
ps->a[ps->top] = x;
}
void StackPop(ST* ps)
{
assert(ps);
assert(ps->top >= 0);
ps->top--;
}
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == -1;
}
int StackSize(ST* ps)
{
assert(ps);
return ps->top + 1;
}
STDataType StackTop(ST* ps)
{
assert(ps);
assert(ps->top >= 0);
return ps->a[ps->top];
}
用栈实现队列
typedef struct
{
ST st1;
ST st2;
} MyQueue;
MyQueue* myQueueCreate()
{
MyQueue* newQue = (MyQueue*)malloc(sizeof(MyQueue));
assert(newQue);
StackInit(&newQue->st1);
StackInit(&newQue->st2);
return newQue;
}
void myQueuePush(MyQueue* obj, int x)
{
assert(obj);
if (!StackEmpty(&obj->st2))
{
while (StackSize(&obj->st2) > 0)
{
StackPush(&obj->st1, StackTop(&obj->st2));
StackPop(&obj->st2);
}
}
StackPush(&obj->st1, x);
}
int myQueuePop(MyQueue* obj)
{
assert(obj);
if (!StackEmpty(&obj->st1))
{
while (StackSize(&obj->st1) > 1)
{
StackPush(&obj->st2, StackTop(&obj->st1));
StackPop(&obj->st1);
}
}
int headOfQue;
if (!StackEmpty(&obj->st1))//如果上一行还剩一个,则他就是队列头也是要删除的
{
headOfQue = StackTop(&obj->st1);
StackPop(&obj->st1);
}
else if(StackEmpty(&obj->st1)&&!StackEmpty(&obj->st2))//如果上一行已经没了,则说明全在下一行,则直接从下一行开始删
{
headOfQue = StackTop(&obj->st2);
StackPop(&obj->st2);
}
else
{
assert(0);
}
return headOfQue;
}
int myQueuePeek(MyQueue* obj)
{
assert(obj);
if (!StackEmpty(&obj->st1))
{
while (StackSize(&obj->st1) > 0)
{
StackPush(&obj->st2, StackTop(&obj->st1));
StackPop(&obj->st1);
}
}
return StackTop(&obj->st2);
}
bool myQueueEmpty(MyQueue* obj)
{
assert(obj);
return StackEmpty(&obj->st1) && StackEmpty(&obj->st2);
}
void myQueueFree(MyQueue* obj)
{
printf("LLL");
assert(obj);
StackDestroy(&obj->st1);
StackDestroy(&obj->st2);
free(obj);
}
测试函数:
int main()
{
MyQueue* que = myQueueCreate();
myQueuePush(que, 1);
myQueuePush(que, 2);
myQueuePeek(que);
myQueuePop(que);
myQueueEmpty(que);
myQueueFree(que);
}