数据结构算法 - 栈和队列

Posted 开发小干货

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构算法 - 栈和队列相关的知识,希望对你有一定的参考价值。

原文转载自:

https://www.jianshu.com/p/9edd74769f21


栈和队列在数据结构和算法学习中,是比较容易理解的。但有时候感觉自己掌握了栈和队列,可是在写的时候遇到不同的情况,就不会处理了,因此自己还是想再总结回顾一下。

栈:
是一端受限,一端允许进行操作的线性表。即:先放的后取,后放的先取。就是我们通常说的“先进后出”(FILO)。存储结构最常见的有两种:一种是顺序存储,一种是链式存储。其中顺序存储就是之前讲的数组,链式存储就是之前讲的链表。

队列:
像栈一样,队列也是一种线性表,它的特性是“先进先出”(FIFO),插入在一端,删除在另一端。就像排队一样,刚来的人入队(push)要排在队尾,每次出队(pop)的都是队首的人。

具体的使用场景还是比较多的如:进制的转换,中缀和后缀表达式,迷宫求解,文本编辑器,二叉树遍历等等,解决方案都需要用到栈和队列的思想。下面我们就来写一写栈和队列的实现。

/** * 判断栈是否为空 */template<class E>bool Stack<E>::isEmpty() { return top == -1;}
/** * 顶部元素弹栈 */template<class E>E Stack<E>::pop() { assert(top >= 0); return array[top--];}
/** * 获取栈顶的元素 */template<class E>E Stack<E>::peek() { assert(top >= 0); return array[top];}
/** * 元素压栈 */template<class E>void Stack<E>::push(E e) { if (top + 1 == size) { growArray(); } array[++top] = e;}
/** * 扩容数组 */template<class E>void Stack<E>::growArray() { size += size >> 1; array = (E *) realloc(array, size * sizeof(E));}


用数组来实现一个栈挺简单的,那如果用数组来实现一个队列呢?队列是先进先出的,那么每次出队列的时候我们需要移除第一个元素,因为是存储结构是数组,后面的元素就都需要往前面挪动,时间复杂度是 O(n)。这个时候我们不妨想一下有没办法可以不用元素,将时间复杂度转换为 O(1) 级别的?答案是:双向数组。

template<class E>ArrayQueue<E>::ArrayQueue(int size) { // 确保数组的长度是 2 的幂次 int init_size = 8; if (size >= init_size) { init_size = size; init_size |= init_size >> 1; init_size |= init_size >> 2; init_size |= init_size >> 4; init_size |= init_size >> 8; init_size |= init_size >> 16; init_size += 1; } array = (E *) malloc(sizeof(E) * init_size); this->size = init_size;}
template<class E>void ArrayQueue<E>::push(E e) { head = (head - 1) & (size - 1); array[head] = e; if (head == tail) { growArray(); }}
template<class E>E ArrayQueue<E>::pop() { tail = (tail - 1) & (size - 1); return array[tail];}
template<class E>E ArrayQueue<E>::peek() { return array[(tail - 1) & (size - 1)];}
template<class E>bool ArrayQueue<E>::isEmpty() { return tail == head;}
template<class E>ArrayQueue<E>::~ArrayQueue() { delete[] array;}/*** 开辟新的数组并调整元素循序**/template<class E>void ArrayQueue<E>::growArray() { int new_size = size << 1; E *new_array = (E *) malloc(new_size * sizeof(E));
// 把数组后面的元素逻动到前面 int r = size - tail; copyArrayElement(array, head, new_array, 0, r); // 把数组前面的元素逻动到后面 copyArrayElement(array, 0, new_array, r, head); // 释放就内存 free(array); array = new_array; // 重新改变指向 head = 0; tail = size; size = new_size;}

以上是关于数据结构算法 - 栈和队列的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法学习笔记栈和队列

浅谈算法和数据结构:栈和队列

数据结构与算法学习笔记 栈和队列Ⅰ

数据结构与算法系列研究二——栈和队列

算法:栈和队列

《线性表的插入和删除算法实现》以及《栈和队列的插入和删除算法实现》的c语言代码