zoukankan      html  css  js  c++  java
  • 数据结构与算法之二叉树 ——in dart

    用dart语言实现的二叉树,实现了插入、查找、删除,中序遍历、前序、后序遍历等功能。

      1 class BinaryTree<E extends Comparable> {
      2   Node<E> _root;
      3   int _nodeNumbers;
      4 
      5   BinaryTree() : _nodeNumbers = 0;
      6 
      7   factory BinaryTree.from(Iterable<E> elements) {
      8     var tree = BinaryTree<E>();
      9     for (var e in elements) tree.insert(e);
     10     return tree;
     11   }
     12 
     13   bool get isEmpty => _root == null;
     14   int get nodeNumbers => _nodeNumbers;
     15 
     16   void clear() {
     17     _root = null;
     18     _nodeNumbers = 0;
     19   }
     20 
     21   bool delete(E value) {
     22     var deleted = find(value);
     23     if (deleted == null) return false;
     24     _delete(deleted);
     25     _nodeNumbers--;
     26     return true;
     27   }
     28 
     29   Node<E> find(E value) {
     30     var current = _root;
     31     while (current != null) {
     32       var c = value.compareTo(current.value);
     33       if (c == 0) break;
     34       current = c < 0 ? current.leftChild : current.rightChild;
     35     }
     36     return current;
     37   }
     38 
     39   void insert(E value) {
     40     var inserted = Node(value);
     41     if (isEmpty) {
     42       _root = inserted;
     43     } else {
     44       var current = _root;
     45       while (current != null) {
     46         if (value.compareTo(current.value) <= 0) {
     47           if (current.leftChild == null) {
     48             current.leftChild = inserted;
     49             inserted.parent = current;
     50             break;
     51           } else {
     52             current = current.leftChild;
     53           }
     54         } else {
     55           if (current.rightChild == null) {
     56             current.rightChild = inserted;
     57             inserted.parent = current;
     58             break;
     59           } else {
     60             current = current.rightChild;
     61           }
     62         }
     63       }
     64     }
     65     _nodeNumbers++;
     66   }
     67 
     68   void traverse(void func(E value), [TraverseOrder order]) {
     69     _traverse(_root, order, func);
     70   }
     71 
     72   E get max {
     73     if (isEmpty) throw TreeEmptyException();
     74     var maxNode = _root;
     75     while (maxNode.rightChild != null) maxNode = maxNode.rightChild;
     76     return maxNode.value;
     77   }
     78 
     79   E get min {
     80     if (isEmpty) throw TreeEmptyException();
     81     return _minNode(_root).value;
     82   }
     83 
     84   Node<E> _minNode(Node<E> root) {
     85     var minNode = root;
     86     while (minNode.leftChild != null) minNode = minNode.leftChild;
     87     return minNode;
     88   }
     89 
     90   void _delete(Node<E> deleted) {
     91     var successor = _successor(deleted);
     92     if (successor != null) _delete(successor);
     93     if (deleted == _root) _root = successor;
     94     _replace(deleted, successor);
     95   }
     96 
     97   static void _replace<E>(Node<E> deleted, Node<E> successor) {
     98     if (deleted.parent != null) {
     99       if (deleted.parent.leftChild == deleted)
    100         deleted.parent.leftChild = successor;
    101       else
    102         deleted.parent.rightChild = successor;
    103     }
    104 
    105     if (successor != null) {
    106       successor.parent = deleted.parent;
    107       successor.leftChild = deleted.leftChild;
    108       successor.rightChild = deleted.rightChild;
    109       if (deleted.leftChild != null) deleted.leftChild.parent = successor;
    110       if (deleted.rightChild != null) deleted.rightChild.parent = successor;
    111     }
    112   }
    113 
    114   Node<E> _successor(Node<E> node) =>
    115       node.rightChild != null ? _minNode(node.rightChild) : node.leftChild;
    116 
    117   static void _traverse<E>(Node<E> root, TraverseOrder order, void func(E e)) {
    118     if (root == null) return;
    119     switch (order) {
    120       case TraverseOrder.preOrder:
    121         func(root.value);
    122         _traverse(root.leftChild, order, func);
    123         _traverse(root.rightChild, order, func);
    124         break;
    125       case TraverseOrder.postOrder:
    126         _traverse(root.leftChild, order, func);
    127         _traverse(root.rightChild, order, func);
    128         func(root.value);
    129         break;
    130       default:
    131         _traverse(root.leftChild, order, func);
    132         func(root.value);
    133         _traverse(root.rightChild, order, func);
    134     }
    135   }
    136 }
    137 
    138 enum TraverseOrder { preOrder, inOrder, postOrder }
    139 
    140 class Node<E> {
    141   E value;
    142   Node<E> parent, leftChild, rightChild;
    143 
    144   Node(this.value);
    145 }
    146 
    147 
    148 class TreeEmptyException implements Exception {
    149   const TreeEmptyException();
    150   String toString() => 'TreeEmptyException';
    151 }
  • 相关阅读:
    命令窗口
    文件压缩,文件夹压缩
    objectarx之工具
    Quick Search Articles in My Blog
    Draw graph(network) with nx_pydot in networkx
    How to Share Wired Internet Via Wi-Fi and Vice Versa on Linux
    Deluge: Enables BT download on your Raspberry Pi
    你还在想用 nextCloud 自建NAS? 何不试试P2P Sync?
    screen 命令使用 keep session running after ssh logout
    Zotero: add a history feature for paper viewing
  • 原文地址:https://www.cnblogs.com/outerspace/p/10457938.html
Copyright © 2011-2022 走看看