zoukankan      html  css  js  c++  java
  • 二叉树(一)

    二叉树,结合了两种数据结构的优点:一种是有序数组,一种是链表。在树中查找数据项的速度和在有序数组查找一样快;并且插入和删除数据项的速度和链表一样快。

    1)在有序数组插入数据太慢:通过二分查找找到该位置,但每次所有比新数据大的坐标都要往后移动一位。不适合于频繁插入和删除数据的操作。
    2)在链表查找太慢:每次查找都必须从表头开始查找,即便是有序链表也是一样。(当然有序链表通过指定值找到该链接点的速度比无序链表快一些)


    树的术语:

    1)路径:顺着节点的边从一个节点走到另一个节点,所经过的节点顺序排列就称为“路径”。

    2)根:一棵树只有一个根,最顶端的位置,而且从根到每个节点的路径仅有一条。

    3)父节点:每个节点(除了根)都有一条向上连接到另一个节点,那么上面的节点就称为“父节点”。

    4)子节点:每个节点都有一条或多条向下连接到其它的节点,那么下面的节点就称为“子节点”。

    5)叶节点:没有子节点的节点就称为“叶节点”。

    6)子树:每个节点都可以是子树的根,它和它所有的子节点、子节点的子节点都含在子树中。一个节点的子树包含它所有的子孙。

    7)访问:当程序流程到达某个节点,并进行相应的操作。就称“访问”这个节点。

    8)层:一个节点的层数是从根开始到这个节点有多少代,假设根是0层,那么它的子节点是1层,再下一节点是2层。。。

    9)关键字:对象中有一个数据域被指定为关键字,这个值常用来查询或其它操作。

    10)二叉树:如果树中每个节点最多只有两个子节点,这样的树被称为“二叉树”。最简单也最常用的。

    11)二叉搜索树:一个节点的左子节点的关键字是小于这个节点,右子结点的关键字是大于或等于这个父节点。

    12)后继:在被删除的节点有两个子节点的情况下,需要拿在中序遍历中,被删的节点的下一个访问的节点替换,该替换的节点叫做被删节点的中序后继,简称后继。

     1 public class Node {
     2 
     3     private Node leftChild;
     4 
     5     private Node rightChild;
     6 
     7     private int iData;
     8 
     9     private double dData;
    10 
    11     public Node(int i, double d) {
    12         iData = i;
    13         dData = d;
    14     }
    15 
    16     public int getiData() {
    17         return iData;
    18     }
    19 
    20     public double getdData() {
    21         return dData;
    22     }
    23 
    24     public Node getLeftChild() {
    25         return leftChild;
    26     }
    27 
    28     public void setLeftChild(Node leftChild) {
    29         this.leftChild = leftChild;
    30     }
    31 
    32     public Node getRightChild() {
    33         return rightChild;
    34     }
    35 
    36     public void setRightChild(Node rightChild) {
    37         this.rightChild = rightChild;
    38     }
    39 
    40     public void displayNode() {
    41         System.out.println("{ " + iData + " , " + dData + " }");
    42     }
    43 
    44 }
      1 public class Tree {
      2 
      3     private Node root;
      4 
      5     public boolean isEmpty() {
      6         return root == null;
      7     }
      8 
      9     public void insert(int i, double d) {
     10         Node node = new Node(i, d);
     11         if (isEmpty()) {
     12             root = node;
     13         }
     14         else {
     15             Node current = root;
     16             Node parent = null;
     17             while (current != null) {
     18                 parent = current;
     19                 if (i < current.getiData()) {
     20                     current = current.getLeftChild();
     21                 }
     22                 else {
     23                     current = current.getRightChild();
     24                 }
     25             }
     26             if (i < parent.getiData()) {
     27                 parent.setLeftChild(node);
     28             }
     29             else {
     30                 parent.setRightChild(node);
     31             }
     32         }
     33     }
     34 
     35     public Node find(int key) {
     36         Node current = root;
     37         while (current != null) {
     38             if (key == current.getiData()) {
     39                 return current;
     40             }
     41             else if (key < current.getiData()) {
     42                 current = current.getLeftChild();
     43             }
     44             else {
     45                 current = current.getRightChild();
     46             }
     47         }
     48         return null;
     49     }
     50 
     51     private void inOrder(Node localRoot) {
     52         if (localRoot != null) {
     53             inOrder(localRoot.getLeftChild());
     54             System.out.print("Local Node : ");
     55             localRoot.displayNode();
     56             inOrder(localRoot.getRightChild());
     57         }
     58     }
     59 
     60     private void preOrder(Node localRoot) {
     61         if (localRoot != null) {
     62             System.out.print("Local Node : ");
     63             localRoot.displayNode();
     64             preOrder(localRoot.getLeftChild());
     65             preOrder(localRoot.getRightChild());
     66         }
     67     }
     68 
     69     private void postOrder(Node localRoot) {
     70         if (localRoot != null) {
     71             postOrder(localRoot.getLeftChild());
     72             postOrder(localRoot.getRightChild());
     73             System.out.print("Local Node : ");
     74             localRoot.displayNode();
     75         }
     76     }
     77 
     78     //中序遍历
     79     public void inOrder() {
     80         inOrder(root);
     81     }
     82 
     83     //前序遍历
     84     public void preOrder() {
     85         preOrder(root);
     86     }
     87 
     88     //后序遍历
     89     public void postOrder() {
     90         postOrder(root);
     91     }
     92 
     93     public Node minNode() {
     94         Node current = root;
     95         Node parent = null;
     96         while (current != null) {
     97             parent = current;
     98             current = current.getLeftChild();
     99         }
    100         return parent;
    101     }
    102 
    103     public Node maxNode() {
    104         Node current = root;
    105         Node parent = null;
    106         while (current != null) {
    107             parent = current;
    108             current = current.getRightChild();
    109         }
    110         return parent;
    111     }
    112 
    113     /*
    114      * 删除节点需要考虑3种情况
    115      * 1、该节点没有子节点
    116      * 2、该节点只有一个子节点(用子节点替换被删掉的节点)
    117      * 3、该节点有两个子节点
    118      */
    119     public Node delete(int key) {
    120         Node current = root;
    121         Node parent = null;
    122 
    123         while (current != null) {
    124             if (key == current.getiData()) {
    125                 break;
    126             }
    127             else if (key < current.getiData()) {
    128                 parent = current;
    129                 current = current.getLeftChild();
    130             }
    131             else {
    132                 parent = current;
    133                 current = current.getRightChild();
    134             }
    135         }
    136         if (current == null) {
    137             return null;
    138         }
    139         //1、该节点没有子节点
    140         if (current.getLeftChild() == null && current.getRightChild() == null) {
    141             //判断是否根节点
    142             if (current == root) {
    143                 root = null;
    144             }
    145             else {
    146                 if (key < parent.getiData()) {
    147                     parent.setLeftChild(null);
    148                 }
    149                 else {
    150                     parent.setRightChild(null);
    151                 }
    152             }
    153         }
    154         //2、该节点只有一个子节点
    155         else if (current.getLeftChild() == null) {
    156             if (current == root) {
    157                 root = null;
    158             }
    159             else {
    160                 if (key < parent.getiData()) {
    161                     parent.setLeftChild(current.getRightChild());
    162                 }
    163                 else {
    164                     parent.setRightChild(current.getRightChild());
    165                 }
    166             }
    167         }
    168         else if (current.getRightChild() == null) {
    169             if (current == root) {
    170                 root = null;
    171             }
    172             else {
    173                 if (key < parent.getiData()) {
    174                     parent.setLeftChild(current.getLeftChild());
    175                 }
    176                 else {
    177                     parent.setRightChild(current.getLeftChild());
    178                 }
    179             }
    180         }
    181         //3、该节点有两个子节点
    182         else {
    183             Node successor = getSuccessor(current);
    184             if (current == root) {
    185                 root = successor;
    186             }
    187             else {
    188                 if (key < parent.getiData()) {
    189                     parent.setLeftChild(successor);
    190                 }
    191                 else {
    192                     parent.setRightChild(successor);
    193                 }
    194             }
    195             successor.setLeftChild(current.getLeftChild());
    196         }
    197         return current;
    198 
    199     }
    200 
    201     private Node getSuccessor(Node delNode) {
    202         Node successorParent = delNode;
    203         Node successor = delNode;
    204         Node current = delNode.getRightChild();
    205         while (current != null) {
    206             successorParent = successor;
    207             successor = current;
    208             current = current.getLeftChild();
    209         }
    210         if (successor != delNode.getRightChild()) {
    211             successorParent.setLeftChild(successor.getRightChild());
    212             successor.setRightChild(delNode.getRightChild());
    213         }
    214         return successor;
    215     }
    216 
    217 }
     1     public static void main(String[] args) {
     2         Tree tree = new Tree();
     3         tree.insert(50, 1.5);
     4         tree.insert(25, 1.6);
     5         tree.insert(75, 1.7);
     6         tree.insert(12, 1.8);
     7         tree.insert(37, 1.9);
     8         tree.insert(43, 2.0);
     9         tree.insert(30, 2.1);
    10         tree.insert(33, 2.2);
    11         tree.insert(87, 2.3);
    12         tree.insert(77, 2.4);
    13         tree.insert(78, 2.5);
    14         tree.insert(74, 2.5);
    15         tree.insert(90, 2.6);
    16         tree.insert(102, 2.7);
    17         tree.insert(107, 2.8);
    18         tree.insert(101, 2.9);
    19         tree.inOrder();
    20         System.out.println("---------------------------");
    21         tree.delete(12);
    22         tree.delete(30);
    23         tree.delete(87);
    24         tree.inOrder();
    25     }

    打印结果:
    Local Node : { 12 , 1.8 }
    Local Node : { 25 , 1.6 }
    Local Node : { 30 , 2.1 }
    Local Node : { 33 , 2.2 }
    Local Node : { 37 , 1.9 }
    Local Node : { 43 , 2.0 }
    Local Node : { 50 , 1.5 }
    Local Node : { 74 , 2.5 }
    Local Node : { 75 , 1.7 }
    Local Node : { 77 , 2.4 }
    Local Node : { 78 , 2.5 }
    Local Node : { 87 , 2.3 }
    Local Node : { 90 , 2.6 }
    Local Node : { 101 , 2.9 }
    Local Node : { 102 , 2.7 }
    Local Node : { 107 , 2.8 }
    ---------------------------
    Local Node : { 25 , 1.6 }
    Local Node : { 33 , 2.2 }
    Local Node : { 37 , 1.9 }
    Local Node : { 43 , 2.0 }
    Local Node : { 50 , 1.5 }
    Local Node : { 74 , 2.5 }
    Local Node : { 75 , 1.7 }
    Local Node : { 77 , 2.4 }
    Local Node : { 78 , 2.5 }
    Local Node : { 90 , 2.6 }
    Local Node : { 101 , 2.9 }
    Local Node : { 102 , 2.7 }
    Local Node : { 107 , 2.8 }

  • 相关阅读:
    《中小学生Python编程入门指南》1.1 什么是编程
    《中小学生Python编程入门指南》前言
    简单的番茄工作法倒计时(源码)
    关于AE
    Blender2.5快捷键
    关于Blender
    随意设置控件每一个角的倒角
    关于多个block问题
    UICollectionViewCell--查找cell上的按钮点击后,对应的是哪个cell
    UIMenuItem
  • 原文地址:https://www.cnblogs.com/xuekyo/p/2775873.html
Copyright © 2011-2022 走看看