zoukankan      html  css  js  c++  java
  • 二叉树

     

    二叉树

    二叉树基本性质
    1. 第 i 层:至多 2^(i-1) 个结点
    2. 深度为k,至多 2^k - 1 个结点,至少 k 个结点
    3. 叶子n0个,度为2的结点n2个:n0 = n2 + 1
    4. 完全二叉树:n个结点,则深度为 [ log2(n)] + 1
    5. 完全二叉树(顺序表存储,下标从1开始)下标关系:双亲[ i / 2 、左孩子 2 * i 、右孩子 2 * i + 1
     
    存储结构
    顺序存储
    二叉链表
    三叉链表
    线索链表
     
     
     
    二叉树实现(二叉链表
    二叉树结点
    1.     publicclassBiNode{
    2.         char data;
    3.         BiNode left;
    4.         BiNode right;
    5.         int flag =0;//供非递归后序遍历使用
    6.     }
    初始化
    1.     privatestaticint i;
    2.     publicBinaryTree(char[] pre){
    3.         i =0;
    4.         root = create(pre);
    5.     }
    6.  
    7.     //初始化(先序遍历顺序存放数组、'#'表示null)
    8.     privateBiNode create(char[] pre)
    9.     {
    10.         if(i < pre.length)
    11.         {
    12.             if(pre[i]=='#')                             //结点为空
    13.             {
    14.                 i++;
    15.                 return null;
    16.             }
    17.  
    18.             BiNode p =newBiNode(pre[i], null, null);    //结点非空
    19.             i++;
    20.             p.left = create(pre);                         //递归建立左子树
    21.             p.right = create(pre);                       //递归建立右子树
    22.             return p;
    23.         }
    24.         return null;
    25.     }
    遍历(递归)
    • 先序遍历
    1.     publicvoid preOrder(){
    2.         preOrder(root);
    3.     }
    4.     privatevoid preOrder(BiNode root){
    5.         if(root == null)return;
    6.  
    7.         System.out.print(root.data);       //访问结点
    8.         preOrder(root.left);
    9.         preOrder(root.right);
    10.     }
    • 中序遍历
    1.    publicvoid inOrder(){
    2.         inOrder(root);
    3.     }
    4.     privatevoid inOrder(BiNode root){
    5.         if(root == null)return;
    6.  
    7.         inOrder(root.left);
    8.         System.out.print(root.data);      //访问结点
    9.         inOrder(root.right);
    10.     }
    • 后序遍历
    1.     publicvoid postOrder(){
    2.         postOrder(root);
    3.     }
    4.     privatevoid postOrder(BiNode root){
    5.         if(root == null)return;
    6.  
    7.         postOrder(root.left);
    8.         postOrder(root.right);
    9.         System.out.print(root.data);     //访问结点
    10.     }
    • 层序遍历
    1.     publicvoid levelOrder(){
    2.         levelOrder(root);
    3.     }
    4.     privatevoid levelOrder(BiNode root){
    5.         LinkedList<BiNode>queue=newLinkedList<BiNode>();  //LinkedList实现了Queue接口
    6.  
    7.         BiNode p = root;
    8.         while(p != null){
    9.             System.out.print(p.data);    //访问结点
    10.  
    11.             if(p.left != null)
    12.                 queue.add(p.left);
    13.             if(p.right != null)
    14.                 queue.add(p.right);
    15.  
    16.             p =queue.poll();           //队头出队并返回为p
    17.         }
    18.     }
     
    遍历(非递归)
    • 先序遍历
    1.     privatevoid preOrder(BiNode head){
    2.         LinkedList<BiNode> s =newLinkedList<BiNode>();
    3.  
    4.         while(head != null ||!s.isEmpty())
    5.         {
    6.             while(head != null)                //访问左子树
    7.             {
    8.                 System.out.print(head.data);    //访问左子树
    9.                 s.push(head);                    //结点入栈(待后面找其右子树使用)= =(“递归”)
    10.                 head = head.left;
    11.             }
    12.  
    13.             if(!s.isEmpty())                   //转向右子树
    14.             {
    15.                 head = s.peek().right;     //转向右子树
    16.                 s.pop();                        //结点出栈(已经找到其右子树)= =(“递归结束”)
    17.             }
    18.         }
    19.     }
     
     
     
    • 中序遍历
    1.     privatevoid inOrder2(BiNode head){
    2.         LinkedList<BiNode> s =newLinkedList<BiNode>();
    3.  
    4.         while(head != null ||!s.isEmpty())
    5.         {
    6.             while(head != null)                //左子树入栈
    7.             {
    8.                 s.push(head);                    //结点入栈(待后面找其右子树使用)= =(“递归”)
    9.                 head = head.left;
    10.             }
    11.  
    12.             System.out.print(s.peek().data);    //访问左子树
    13.  
    14.             if(!s.isEmpty())                   //转向右子树
    15.             {
    16.                 head = s.peek().right;         //转向右子树
    17.                 s.pop();                        //结点出栈(已经找到其右子树)= =(“递归结束”)
    18.             }
    19.         }
    20.     }
     
     
    • 后序遍历
    1.     //后序遍历特点:递归左右子树后,还需访问结点:
    2.     //1、左子树入栈
    3.     //2、“两次出栈”(用flag标记模仿):第一次是为了找到左子树相应的右子树结点;第二次是为了访问结点
    4.     privatevoid postOrder2(BiNode head){
    5.         LinkedList<BiNode> s =newLinkedList<BiNode>();
    6.  
    7.         while(head != null ||!s.isEmpty())
    8.         {
    9.             while(head != null)                        //左子树入栈
    10.             {
    11.                 head.flag =1;
    12.                 s.push(head);                            //结点连同flag入栈(待后面找其右子树使用)= =(“递归”)
    13.                 head = head.left;
    14.             }
    15.  
    16.             while(!s.isEmpty()&& s.peek().flag ==2)  //若flag为2(已经找到其右子树出过一次栈),访问结点
    17.             {
    18.                 System.out.print(s.peek().data);       //访问结点元素
    19.                 s.pop();                               //(第二次“结点出栈”)实际结点出栈(已经访问结点元素)= =(“递归结束”)
    20.             }
    21.  
    22.             if(!s.isEmpty())                         //flag为1,转向右子树
    23.             {
    24.                 head = s.peek().right;                //转向右子树
    25.                 s.peek().flag =2;                    //(第一次“flag模拟出栈”)标记为2,但实际结点不出栈(已经找到其右子树)
    26.             }
    27.  
    28.         }
    29.     }
    插入
    1.   //在p结点后插入data
    2.     publicvoid insert(BiNode p,char data, boolean left){
    3.         if(p != null){
    4.             if(left)                //插入位置为左孩子
    5.                 p.left =newBiNode(data,p.left,null);
    6.             else                   //插入位置为右孩子
    7.                 p.right =newBiNode(data,p.right,null);
    8.         }
    9.     }
     
    删除
    1.     //删除p的一个子树
    2.     publicvoiddelete(BiNode p, boolean left){
    3.         if(p != null){
    4.             if(left)              //删除目标为左子树
    5.                 p.left = null;
    6.             else                  //删除目标为右子树
    7.                 p.right = null;
    8.         }
    9.     }
     
     

    哈夫曼树(最优二叉树)

    哈夫曼树的存储结构:
    哈夫曼算法:
     


    一般树的存储结构

    • 双亲表示法:
     
    • 孩子表示法:
    1、多重链表表示法
    2、孩子链表表示法
     
    • 双亲孩子表示法:
     
    • 孩子兄弟表示法:
     

    树与森林的转换

     
     
     
     

    整理by Doing

    参考资料:《数据结构(C++版)》王红梅

  • 相关阅读:
    spymemcache与spring结合
    Turtle库的学习积累
    汉诺塔绘图学习
    计算圆周率π和显示进度条
    川菜 in English
    一些必不可少的Sublime Text 2插件 钟磊的专栏 博客频道 CSDN.NET
    \usepackage{natbib}在latex模板写作中的心得_格致轩_百度空间
    Geant4新版本:新安装方法,新运行方式
    ubuntu系统备份
    Latex数学公式中的空格
  • 原文地址:https://www.cnblogs.com/Doing-what-I-love/p/5535020.html
Copyright © 2011-2022 走看看