栈(stack)又称为堆栈或堆叠, 栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。
它按照先进后出LIFO, Last In First Out)的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶。读数据时, 从栈顶开始弹出数据。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。
允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;插入一般称为进栈(PUSH),删除则称为退栈(POP)。
数组实现
- Stack():创建一个新的空栈。
- push(item):添加一个新的元素 item 到栈顶。
- pop():弹出栈顶元素。
- peek():返回栈顶元素。
- isEmpty():判断栈是否为空。
- size():返回栈的元素个数。
class Stack {
/// 栈: 后进先出, 数组的末尾进行插入和删除, 所以选定末尾为栈顶。
/// _list数组、_top(int)表示栈顶位置。
late List _list;
int _top = -1;
int _size = 0;
Stack(int size) {
_size = size;
_list = List.generate(size, (index) => null);
}
/// 入栈
push(item) {
if (isFull()) throw StackOverFlowException;
_list[++_top] = item;
}
/// 弹出栈顶元素
pop() {
if (isEmpty()) throw StackEmptyException;
return _list[_top--];
}
/// 返回栈顶元素
peek() {
if (isEmpty()) throw StackEmptyException;
return _list[_top];
}
/// 判断栈是否为空
bool isEmpty() {
return _top == -1;
}
/// 判断栈是否满
bool isFull() {
return _top == _size - 1;
}
/// 返回栈的元素个数
int size() {
return _top + 1;
}
/// 打印栈
void display() {
print("Stack: $_list\n");
}
}
class StackOverFlowException implements Exception {
const StackOverFlowException();
String toString() => 'StackOverFlowException';
}
class StackEmptyException implements Exception {
const StackEmptyException();
String toString() => 'StackEmptyException';
}
void main() {
Stack stack = new Stack(6);
stack.push('1');
stack.push("2");
stack.push('3');
stack.push("4");
stack.push('5');
stack.push("6");
stack.display();
var popData;
popData = stack.pop();
print("Pop $popData from stack\n");
popData = stack.pop();
print("Pop $popData from stack\n");
stack.display();
}
链表实现
单链表头插入一致, 在表头插入数据。
class Node {
/// 节点
var item;
Node? next;
Node({this.item, this.next});
}
class Stack {
/// 栈: 单链表头插入一致, 在表头插入数据。
/// 头部指针: _head
Node? _head;
/// 入栈
push(item) {
final Node node = Node(item: item);
node.next = _head;
_head = node;
}
/// 弹出栈顶元素
pop() {
if (isEmpty()) throw StackEmptyException;
/// 取出头部指针保存的值
final item = _head?.item;
_head = _head?.next;
return item;
}
/// 判断栈是否为空
bool isEmpty() {
return _head == null;
}
/// 打印栈
void display() {
Node? cur = _head;
while (cur != null) {
print("Stack: ${cur.item}\n");
cur = cur.next;
}
}
}
class StackOverFlowException implements Exception {
const StackOverFlowException();
String toString() => 'StackOverFlowException';
}
class StackEmptyException implements Exception {
const StackEmptyException();
String toString() => 'StackEmptyException';
}
void main() {
Stack stack = new Stack();
stack.push('1');
stack.push("2");
stack.push('3');
stack.push("4");
stack.push('5');
stack.push("6");
stack.display();
var popData;
popData = stack.pop();
print("Pop $popData from stack\n");
popData = stack.pop();
print("Pop $popData from stack\n");
stack.display();
}