数据结构和算法--二叉树学习

来源:互联网 发布:普法网络知识竞赛答题 编辑:程序博客网 时间:2024/06/05 06:22

二叉树的遍历

对于二叉树来讲最主要、最基本的运算是遍历。
    遍历二叉树 是指以一定的次序访问二叉树中的每个结点。所谓 访问结点 是指对结点进行各种操作的简称。例如,查询结点数据域的内容,或输出它的值,或找出结点位置,或是执行对结点的其他操作。遍历二叉树的过程实质是把二叉树的结点进行线性排列的过程。假设遍历二叉树时访问结点的操作就是输出结点数据域的值,那么遍历的结果得到一个线性序列。

从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:
     (1)访问结点本身(N),
     (2)遍历该结点的左子树(L),
     (3)遍历该结点的右子树(R)。
以上三种操作有六种执行次序:
     NLR、LNR、LRN、NRL、RNL、RLN。
注意:
    前三种次序与后三种次序对称,故只讨论先左后右的前三种次序。

  由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtlee)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

树执行查找、删除、插入的时间复杂度都是O(logN)

举例:


 System.out.println("*******(前序遍历)[ABDECF]遍历*****************");  

 System.out.println("*******(中序遍历)[DBEACF]遍历*****************");  

 System.out.println("*******(后序遍历)[DEBFCA]遍历*****************");  



  1. 先序遍历:  
  2. 1 2 4 8 9 5 3 6 7   
  3. 中序遍历:  
  4. 8 4 9 2 5 1 6 3 7   
  5. 后序遍历:  
  6. 8 9 4 5 2 6 7 3 1   

算法代码实现

定义一个节点类,使节点与二叉树操作分离

class Node {    int  value;    Node leftChild;    Node rightChild;         Node(int value) {        this.value = value;    }         public void display() {        System.out.print(this.value + "\t");    }     @Override    public String toString() {        // TODO Auto-generated method stub        return String.valueOf(value);    }}
需要实现的二叉树操作

class BinaryTree {    private Node root = null;         BinaryTree(int value) {        root = new Node(value);        root.leftChild  = null;        root.rightChild = null;    }    public Node findKey(int value) {}   //查找        public String insert(int value) {}  //插入        public void inOrderTraverse() {}    //中序遍历        public void preOrderTraverse() {}   //前序遍历        public void postOrderTraverse() {}  //后序遍历        public int getMinValue() {}         //得到最小(大)值        public boolean delete(int value) {} //删除}
查找数据:

public Node findKey(int value) {      Node current = root;      while (true) {          if (value == current.value) {              return current;          } else if (value < current.value) {              current = current.leftChild;          } else if (value > current.value) {              current = current.rightChild;          }                     if (current == null) {              return null;          }      }  }

插入数据:与查找数据类似,不同点在于当节点为空时,不是返回而是插入

public String insert(int value) {      String error = null;             Node node = new Node(value);      if (root == null) {          root = node;          root.leftChild  = null;          root.rightChild = null;      } else {          Node current = root;          Node parent = null;          while (true) {              if (value < current.value) {                  parent = current;                  current = current.leftChild;                  if (current == null) {                      parent.leftChild = node;                      break;                  }              } else if (value > current.value) {                  parent = current;                  current = current.rightChild;                  if (current == null) {                      parent.rightChild = node;                      break;                  }              } else {                  error = "having same value in binary tree";              }             } // end of while      }      return error;  }
遍历数据:

 

1)中序遍历:最常用的一种遍历方法

/**   * //中序遍历(递归):   *    1、调用自身来遍历节点的左子树   *    2、访问这个节点   *    3、调用自身来遍历节点的右子树   */  public void inOrderTraverse() {      System.out.print("中序遍历:");      inOrderTraverse(root);      System.out.println();  }     private void inOrderTraverse(Node node) {      if (node == null)           return ;             inOrderTraverse(node.leftChild);      node.display();      inOrderTraverse(node.rightChild);  }

2)前序遍历:

/**   * //前序遍历(递归):   *    1、访问这个节点   *    2、调用自身来遍历节点的左子树   *    3、调用自身来遍历节点的右子树   */  public void preOrderTraverse() {      System.out.print("前序遍历:");      preOrderTraverse(root);      System.out.println();  }     private void preOrderTraverse(Node node) {      if (node == null)           return ;             node.display();      preOrderTraverse(node.leftChild);      preOrderTraverse(node.rightChild);  }
3)后序遍历:

**   * //后序遍历(递归):   *    1、调用自身来遍历节点的左子树   *    2、调用自身来遍历节点的右子树   *    3、访问这个节点   */  public void postOrderTraverse() {      System.out.print("后序遍历:");      postOrderTraverse(root);      System.out.println();  }     private void postOrderTraverse(Node node) {      if (node == null)           return ;             postOrderTraverse(node.leftChild);      postOrderTraverse(node.rightChild);      node.display();  }

得到最小(大)值:依次向左(右)直到空为之

public int getMinValue() {      Node current = root;      while (true) {          if (current.leftChild == null)              return current.value;                     current = current.leftChild;      }  }

参考文章:http://ocaicai.iteye.com/blog/1047397

         http://blog.csdn.net/wuwenxiang91322/article/details/12231657

        http://www.2cto.com/kf/201608/541695.html

面试参考:http://blog.csdn.net/luckyxiaoqiang/article/details/7518888/




0 0
原创粉丝点击