编程总结
每每刷完一道题后,其思想和精妙之处没有地方记录,本篇博客用以记录刷题过程中的遇到的算法和技巧
232. 用栈实现队列
思路:

要点就是,先要有栈的数据结构及其实现,然后用两个栈,一个作in stack,一个作out stack来实现队列的先入先出:
a. 进队列,都默认进到 in stack里;
b. 查队列首元素,要求先入先出,那就得先将 in stack 的数据都放到 out stack 里去,这时 out stack 里的top元素就是队列要出的元素;
c. 出队列时,先判断 out stack是否为空,为空则in2out搬运,否则,直接出out stack的top即可;
/*
1.两个type为int的数组(栈),大小为100
第一个栈stackIn用来存放数据,第二个栈stackOut作为辅助用来输出数据
2.两个指针stackInTop和stackOutTop,分别指向栈顶
*/
typedef struct {
int stackInTop, stackOutTop;
int stackIn[100], stackOut[100];
} MyQueue;
/*
1.开辟一个队列的大小空间
2.将指针stackInTop和stackOutTop初始化为0
3.返回开辟的队列
*/
MyQueue *myQueueCreate() {
MyQueue *queue = (MyQueue *)malloc(sizeof(MyQueue));
queue->stackInTop = 0;
queue->stackOutTop = 0;
return queue;
}
/*
将元素存入第一个栈中,存入后栈顶指针+1
*/
void myQueuePush(MyQueue *obj, int x)
{
obj->stackIn[(obj->stackInTop)++] = x;
}
/*
1.若输出栈为空且当第一个栈中有元素(stackInTop>0时),将第一个栈中元素复制到第二个栈中(stackOut[stackTop2++] = stackIn[--stackTop1])
2.将栈顶元素保存
3.当stackTop2>0时,将第二个栈中元素复制到第一个栈中(stackIn[stackTop1++] = stackOut[--stackTop2])
*/
int myQueuePop(MyQueue *obj)
{
//优化:复制栈顶指针,减少对内存的访问次数
int stackInTop = obj->stackInTop;
int stackOutTop = obj->stackOutTop;
//若输出栈为空
if (stackOutTop == 0) {
//将第一个栈中元素复制到第二个栈中
while (stackInTop > 0) {
obj->stackOut[stackOutTop++] = obj->stackIn[--stackInTop];
}
}
//将第二个栈中栈顶元素(队列的第一个元素)出栈,并保存
int top = obj->stackOut[--stackOutTop];
//将输出栈中元素放回输入栈中
while (stackOutTop > 0) {
obj->stackIn[stackInTop++] = obj->stackOut[--stackOutTop];
}
//更新栈顶指针
obj->stackInTop = stackInTop;
obj->stackOutTop = stackOutTop;
//返回队列中第一个元素
return top;
}
//返回输入栈中的栈底元素
int myQueuePeek(MyQueue *obj)
{
return obj->stackIn[0];
}
//若栈顶指针均为0,则代表队列为空
bool myQueueEmpty(MyQueue *obj)
{
return (obj->stackInTop == 0) && (obj->stackOutTop == 0);
}
//将栈顶指针置0
void myQueueFree(MyQueue *obj)
{
obj->stackInTop = 0;
obj->stackOutTop = 0;
}
225. 用队列实现栈
思路:
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
注意:
你只能使用队列的标准操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
示例:
输入:
[“MyStack”, “push”, “push”, “top”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]
解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False
提示:
1 <= x <= 9
最多调用100 次 push、pop、top 和 empty
每次调用 pop 和 top 都保证栈不为空
#define MAX_NUN 1024
typedef struct {
int head;
int tail;
int size; // 计算队列元素个数
int data[MAX_NUN];
} Queue_t;
bool QueueIsEmpty(Queue_t *queue)
{
return (queue->head == queue->tail);
}
bool QueueIsFull(Queue_t *queue)
{
return (((queue->tail + 1) % queue->size) == queue->head);
}
bool QueuePush(Queue_t *queue, int value) {
if (QueueIsFull(queue)) {
return false;
}
queue->data[queue->tail] = value; // 先入队
queue->tail = (queue->tail + 1) % queue->size; // tail再移动,队尾元素为tail-1.
return true;
}
int QueueFront(Queue_t *queue)
{
if (QueueIsEmpty(queue)) {
return -1;
}
return queue->data[queue->head];
}
int QueueTail(Queue_t *queue)
{
if (QueueIsEmpty(queue)) {
return -1;
}
return queue->data[(queue->tail - 1 + queue->size) % queue->size];
}
bool QueuePop(Queue_t *queue, int *value)
{
if (QueueIsEmpty(queue)) {
return false;
}
*value = queue->data[queue->head];
queue->head = (queue->head + 1) % queue->size;
return true;
}
Queue_t *QueueCreate(int size)
{
Queue_t *queue = (Queue_t *)malloc(sizeof(Queue_t));
queue->tail = 0;
queue->head = 0;
queue->size = size;
memset(queue->data, 0, sizeof(int) * (MAX_NUN));
return queue;
}
void QueueFree(Queue_t *queue)
{
free(queue);
queue = NULL;
}
/*---------------------两个队列实现栈---------------------*/
typedef struct {
Queue_t *queueA;
Queue_t *queueB;
} MyStack;
// Initialize your data structure here.
MyStack *myStackCreate() {
MyStack *stack = (MyStack *)malloc(sizeof(MyStack));
stack->queueA = QueueCreate(20);
stack->queueB = QueueCreate(20);
return stack;
}
// Returns whether the stack is empty.
bool myStackEmpty(MyStack *queue) {
return (QueueIsEmpty(queue->queueA) && QueueIsEmpty(queue->queueB));
}
// Returns whether the stack is empty.
bool myStackFull(MyStack *queue) {
return (QueueIsFull(queue->queueA) || QueueIsFull(queue->queueB));
}
// Push element x onto stack.
void myStackPush(MyStack *queue, int x)
{
if (myStackFull(queue))
return;
Queue_t *enQueue = NULL;
if (!QueueIsEmpty(queue->queueA)) {
enQueue = queue->queueA;
}
else {
enQueue = queue->queueB;
}
QueuePush(enQueue, x);
}
// Removes the element on top of the stack and returns that element.
int myStackPop(MyStack *queue)
{
if (myStackEmpty(queue)) {
return -1;
}
int data;
Queue_t *enQueue = NULL;
Queue_t *deQueue = NULL;
Queue_t *tmpQueue = NULL;
if (!QueueIsEmpty(queue->queueA)) {
deQueue = queue->queueA; // queueA A队列出数据
enQueue = queue->queueB; // queueB B队列收数据
}
else {
deQueue = queue->queueB;
enQueue = queue->queueA;
}
while (deQueue->tail != deQueue->head) {
printf("\n");
QueuePop(deQueue, &data); // 队列1出数据,队列2收数据
if (!QueueIsEmpty(deQueue)) {
// 队列1出完最后一个元素,队列2不接收,直接作为最后一个输出,它就是栈的Top元素
QueuePush(enQueue, data);
}
}
printf("tail is %d, head is %d\n", deQueue->tail, deQueue->head);
return data;
}
// Get the top element.
int myStackTop(MyStack *queue)
{
if (myStackEmpty(queue)) {
return -1;
}
Queue_t *enQueue = NULL;
Queue_t *deQueue = NULL;
int data;
if (!QueueIsEmpty(queue->queueA)) {
deQueue = queue->queueA;
enQueue = queue->queueB;
}
else {
deQueue = queue->queueB;
enQueue = queue->queueA;
}
while (deQueue->tail != deQueue->head) {
QueuePop(deQueue, &data);
QueuePush(enQueue, data);
}
return data;
}
void myStackFree(MyStack *queue) {
QueueFree(queue->queueA);
QueueFree(queue->queueB);
free(queue);
}
队列的典型应用:广度优先遍历
有两种通用的遍历树的策略:
1.深度优先搜索(DFS)
在这个策略中,我们采用深度作为优先级,以便从跟开始一直到达某个确定的叶子,然后再返回根到达另一个分支。
深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序被细分为先序遍历,中序遍历和后序遍历。
2.宽度优先搜索(BFS)
我们按照高度顺序一层一层的访问整棵树,高层次的节点将会比低层次的节点先被访问到。
102. 二叉树的层次遍历
思路:层序遍历和BFS很配哦
给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。

二叉树的层次遍历使用的更多的是利用队列的性质实现BFS,广度优先遍历:
int **levelOrder(struct TreeNode *root, int *returnSize, int **returnColumnSizes)

最低0.47元/天 解锁文章
835

被折叠的 条评论
为什么被折叠?



