数据结构与算法(Dart)之栈(四)

672 阅读1分钟

(stack)又称为堆栈堆叠, 栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。

它按照先进后出LIFO, Last In First Out)的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶。读数据时, 从栈顶开始弹出数据。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。

允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;插入一般称为进栈(PUSH),删除则称为退栈(POP)。

截屏2024-01-23 上午9.27.57.png

数组实现

  • 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();
}

参考资料

数据结构与算法详解

数据结构与算法之Stack(栈)——in dart