二叉树本身就是递归定义的(wikipedia)

To actually define a binary tree in general, we must allow for the possibility that only one of the children may be empty. An artifact, which in some textbooks is called an extended binary tree is needed for that purpose. An extended binary tree is thus recursively defined as:

1.the empty set is an extended binary tree

2.if T1 and T2 are extended binary trees, then denote by T1 • T2 the extended binary tree obtained by adding a root r connected to the left to T1 and to the right to T2 by adding edges when these sub-trees are non-empty.

就是说考虑空集也是“扩展二叉树”,通过一个树节点节点将两个“扩展二叉树”分别作为左右子节点后,以该树节点为根节点构成一棵“扩展二叉树”。

二叉树类型:满二叉树、完全二叉树、完美二叉树、平衡二叉

性质:太多了!!!

存储二叉树节点的方法:

1.节点和引用,这个自不必说。

2.数组:二叉树以隐式广度优先搜索顺序存储在数组中,这种方法节省两个左右子节点引用的内存。

对于以0为索引开头的数组,数组索引值为i的节点,它的左右子节点的索引分别为2i+1,2i+2,而它的父节点数组索引[(i-1)/2]

对于以1为索引开头的数组,数组索引值为i的节点,它的左右子节点的索引分别为2i,2i+1,而它的父节点数组索引[i/2]

存储稠密并且更好的本地引用(数组索引速度快),然而这种存储方法耗费的空间复杂度为O(2^h-n)(深度h,节点数为n的树)

直接上代码:

//二叉树的二叉链表树用根节点来表示
public class BinaryTree<T>{public BinaryNode<T> root;public BinaryTree(){this.root=null;}public BinaryTree(BinaryNode<T> root){this.root=root;}/*先根遍历和中根遍历两种次序可以唯一确定二叉树,perlist和inlist长度为n,序号为0~n-1先根遍历序列prelist的perlist[0]为根节点,在中根遍历序列的inlist中寻找值为perlist[0]的节点,序号为i在inlist中i左边0,i-1为左子树,i+1,n为右子树左子树的先根遍历序列为prelist[1],...,prelist[i]左子树的中根遍历序列为inlist[0],...inlist[i-1]右子树的先根遍历序列为prelist[i+1],...prelist[n-1]右子树的中根遍历序列inlist[i+1],...,inlist[n-1]*/public BinaryTree(T[] prelist,T[] inlist){this.root=create(prelist,inlist,0,0,prelist.length);}public BinaryNode<T> create(T[] prelist,T[] inlist,int preStart,int inStart,int n ){if(n<=0)return null;T e=prelist[preStart];BinaryNode<T> p=new BinaryNode<T>(e);int i=0;while(i<n && !inlist[i+inStart].equals(e))i++;p.left=create(prelist,inlist,preStart+1,inStart,i);p.right=create(prelist,inlist,preStart+i+1,inStart+i+1,n-1-i);return p;}@Overridepublic boolean isEmpty() {// TODO Auto-generated method stubreturn this.root==null;}@Overridepublic int count() {// TODO Auto-generated method stubreturn count(this.root);}public int count(BinaryNode<T> p) {if(p==null)return 0;return 1+count(p.left)+count(p.right);}@Overridepublic int height() {// TODO Auto-generated method stubreturn height(this.root);}//递归调用height求当前节点的高度public int height(BinaryNode<T> p){if(p==null)return 0;int lcount=height(p.left);int rcount=height(p.right);return (lcount>=rcount)?lcount+1:rcount+1;}@Overridepublic void preOrder() {//先根次序遍历:访问根节点,遍历左子树,遍历右子树 TODO Auto-generated method stubSystem.out.print("先根次序遍历二叉树");preOrder(root);System.out.println();}public void preOrder(BinaryNode<T> p){if(p!=null){System.out.print(p.data.toString()+" ");preOrder(p.left);preOrder(p.right);}}/*用非递归先根遍历以node为根节点的(子)树*在二叉树先序遍历非递归算法中,先将根结点压栈,在栈不为空的时候执行循环:让栈顶元素p出栈,访问栈顶元素p,*如果p的右孩子不为空,则让其右孩子先进栈,如果p的左孩子不为空,则再让其左孩子进栈*(注意:进栈顺序一定是先右孩子,再左孩子)。*/public void preOrderNoRecursive(BinaryNode<T> node){LinkedStack<BinaryNode<T>> stack=new LinkedStack<BinaryNode<T>>();BinaryNode<T> p=node;//停止while循环的条件是栈为空并且p指向nullwhile(!stack.isEmpty() || p!=null){while(p!=null){System.out.print(p.data);stack.push(p);//入栈操作表示访问该节点p=p.left;}if(!stack.isEmpty()){p=stack.getTop();stack.pop();p=p.right;}}}public void preOrderNoRecursive2(BinaryNode<T> node){LinkedStack<BinaryNode<T>> stack=new LinkedStack<BinaryNode<T>>();BinaryNode<T> p=node;while(!stack.isEmpty() || p!=null){if(p!=null){System.out.print(p.data);stack.push(p);p=p.left;}else{p=stack.getTop();stack.pop();p=p.right;}}}@Overridepublic void inOrder() {//中根次序遍历:遍历左子树,访问根节点,遍历右子树 TODO Auto-generated method stubSystem.out.print("中根次序遍历二叉树");inOrder(root);System.out.println();}public void inOrder(BinaryNode<T> p){if(p!=null){preOrder(p.left);System.out.print(p.data.toString()+" ");preOrder(p.right);}}//用非递归中根遍历以node为根节点的(子)树public void inOrderNoRecursive(BinaryNode<T> node){System.out.println("非递归中根遍历: ");LinkedStack<BinaryNode<T>> stack=new LinkedStack<BinaryNode<T>>();BinaryNode<T> p=node;while(!stack.isEmpty() || p!=null ){if(p!=null){stack.push(p);p=p.left;}else{p=stack.pop();System.out.print(p.data+" ");p=p.right;}}}@Overridepublic void postOrder() {// 后根次序遍历:遍历左子树,遍历右子树,访问根节点TODO Auto-generated method stubSystem.out.print("后根次序遍历二叉树");postOrder(root);System.out.println();}public void postOrder(BinaryNode<T> p) {if(p!=null){postOrder(p.left);postOrder(p.right);System.out.print(p.data.toString()+" ");}}//对于非递归后根遍历,使用顺序栈比public void postOrderNoRecursive(BinaryNode<T> node){System.out.println("非递归后根遍历: ");SeqStack<BinaryNode<T>> stack=new SeqStack<BinaryNode<T>>();BinaryNode<T> p=node;int[] tag=new int[this.count()];//停止while循环的条件是栈为空并且p指向nullwhile(!stack.isEmpty() || p!=null){while(p!=null){stack.push(p);tag[stack.getTopIndex()]=0;p=p.left;}while(!stack.isEmpty() && tag[stack.getTopIndex()]==1){System.out.print(stack.pop());}if(!stack.isEmpty()){p=stack.getTop();tag[stack.getTopIndex()]=1;p=p.right;}}}public void postOrderNoRecursive2(BinaryNode<T> node){if(node==null)return;LinkedStack<BinaryNode<T>> stack=new LinkedStack<BinaryNode<T>>();stack.push(node);BinaryNode<T> lastPop=node;while(!stack.isEmpty()){BinaryNode<T> top =stack.getTop();if(top.left!=null && top.left!=lastPop && top.right!=lastPop)stack.push(top.left);else if(top.right!=null && top.right!=lastPop && (top.left==lastPop || top.left==null)){stack.push(top.right);}else{stack.pop();lastPop=top;System.out.print(top.data);}}}public String toGenListString(){return "二叉树的广义表形式"+this.toGenListString(this.root);}public String toGenListString(BinaryNode<T> node){if(node==null)return "^";String str=node.data.toString();if(node.left!=null || node.right!=null)str+="("+this.toGenListString(node.left)+","+this.toGenListString(node.right)+")";return str;}public void levelOrder(BinaryNode<T> node) {// TODO Auto-generated method stubLinkedQueue<BinaryNode<T>> q=new LinkedQueue<BinaryNode<T>>();BinaryNode<T> p=node;q.enqueue(p);while(!q.isEmpty()){p=q.dequeu();System.out.print(p.data.toString());if(p.left!=null)q.enqueue(p.left);if(p.right!=null)q.enqueue(p.right);}}@Overridepublic void levelOrder(){levelOrder(this.root);}@Overridepublic BinaryNode<T> search(T key) {// TODO Auto-generated method stubreturn search(this.root,key);}public BinaryNode<T> search(BinaryNode<T> p,T key){if(p==null||key==null)return null;if(p.data.equals(key))return p;BinaryNode<T> find=search(p.left,key);if(find==null)find=search(p.right,key);return find;}@Overridepublic BinaryNode<T> getParent(BinaryNode<T> node) {// TODO Auto-generated method stubreturn getParent(this.root,node);}//查找以p为根的子树中节点node的父节点public BinaryNode<T> getParent(BinaryNode<T> p,BinaryNode<T> node){if(p==null)return null;if(p.left==node||p.right==node)return p;BinaryNode<T> find=getParent(p.left,node);if(find==null)find=getParent(p.right,node);return find;}@Overridepublic void insertRoot(T x) {// TODO Auto-generated method stubBinaryNode<T> new_root=new BinaryNode<T>(x);new_root.left=this.root;   }//插入x作为节点p的左(右)子节点,如果p节点已经存在对应的左(右)节点,则原左(右)节点作为插入节点的左(右)子节点@Overridepublic BinaryNode<T> insertChild(BinaryNode<T> p, T x, boolean leftChild) {// TODO Auto-generated method stubif(p==null || x==null)return null;BinaryNode<T> new_node=new BinaryNode<T>(x);if(leftChild){if(p.left==null)p.left=new_node;else{new_node.left=p.left;p.left=new_node;}}else{if(p.right==null)p.right=new_node;else{new_node.right=p.right;p.right=new_node;}}return new_node;}//删除节点p的左(右)子节点,这里规定将以p的左(右)子节点为根节点的树全部删去@Overridepublic void removeChild(BinaryNode<T> p, boolean leftChild) {// TODO Auto-generated method stubif(p!=null){if(leftChild)p.left=null;elsep.right=null;}}@Overridepublic void removeAll() {// TODO Auto-generated method stubthis.root=null;}public static void main(String[] args){BinaryNode<String> n7=new BinaryNode<String>("H");BinaryNode<String> n6=new BinaryNode<String>("G");BinaryNode<String> n5=new BinaryNode<String>("F");BinaryNode<String> n4=new BinaryNode<String>("E");BinaryNode<String> n3=new BinaryNode<String>("D",n7,null);BinaryNode<String> n2=new BinaryNode<String>("C",n5,n6);BinaryNode<String> n1=new BinaryNode<String>("B",n3,n4);BinaryNode<String> n0=new BinaryNode<String>("A",n1,n2);BinaryTree<String> tree=new BinaryTree<String>(n0);System.out.println(tree.height());System.out.println(tree.count());tree.preOrder();tree.inOrder();tree.postOrder();tree.preOrderNoRecursive(n0);System.out.println();tree.preOrderNoRecursive2(n0);System.out.println();tree.postOrderNoRecursive(n0);System.out.println();tree.postOrderNoRecursive(n2);System.out.println();tree.postOrderNoRecursive2(n0);System.out.println();System.out.println(tree.toGenListString());System.out.println();tree.levelOrder();}
}

打印结果如下:

4
8
先根次序遍历二叉树A B D H E C F G 
中根次序遍历二叉树B D H E A C F G 
后根次序遍历二叉树H D E B F G C A 
ABDHECFG
ABDHECFG
非递归后根遍历: 
HDEBFGCA
非递归后根遍历: 
FGC
HDEBFGCA
二叉树的广义表形式A(B(D(H,^),E),C(F,G))

ABCDEFGH

二叉树(Binary Tree)详解相关推荐

  1. 【数据结构】二叉树 (Binary Tree)

    目录 一. 什么是树? 二. 二叉树 特殊二叉树 二叉树的性质 二叉树的存储 二叉树的遍历 二叉树的基本操作 一.什么是树? 之前咱们学习了一些简单的数据结构,如顺序表,链表,这些都是线性结构,线性结 ...

  2. BTree和B+Tree详解结构

    如果是复合索引: 关键字的排序先排左侧字段,在左侧字段相同的情况下,再排序右侧字段. BTree和B+Tree详解 B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引. ...

  3. 二叉树层次遍历算法 python_二叉树的遍历详解:前、中、后、层次遍历(Python实现)...

    二叉树的遍历详解:前.中.后.层次遍历(Python实现) 二叉树是一种常见的数据结构,而它的常见遍历方法有前序遍历.中序遍历.后续遍历.层次遍历--掌握这几种遍历方法是很有必要的. 假设我们二叉树节 ...

  4. 二叉树遍历算法详解(递归法+非递归法)

    二叉树遍历算法详解 在上一篇C语言实现二叉树中有提到对于二叉树的遍历,包括前序,中序和后续遍历,以及层次遍历 大家已经熟悉了二叉树的前中后序遍历过程,大部分都采用了递归的思想来实现 在leetcode ...

  5. B-Tree 和 B+Tree详解

    B-Tree 和 B+Tree详解 一.什么是B-Tree 1.B-树插入 2.B-树删除 3.总结 二.什么是B+Tree 1.B+树插入 2.B+树删除 3.总结 一.什么是B-Tree B-Tr ...

  6. 二叉树 Binary Tree

    我怀着激动的心 走上了这颗树 今天是2021年11月12日 今天开始上树!!!!!! 生活中的树形结构: 树:  根节点: 一棵树有且只有一个根节点就是最上面的节点 兄弟节点: 每一行的节点  它们具 ...

  7. 『数据结构与算法』解读树(Tree)和二叉树(Binary Tree)!

    『数据结构与算法』解读树(Tree)和二叉树(Binary Tree)! 文章目录 一. 树 1.1. 树的定义 1.2. 树的基本术语 1.3. 树的性质 二. 二叉树 2.1. 二叉树的定义 2. ...

  8. 数据库优化/Linux安装Mysql/B+Tree详解

    一.Linux安装MySQL yum安装 #下载安装源 wget http://repo.mysql.com/mysql57-community-release-el6-8.noarch.rpm #安 ...

  9. [Swift]LeetCode968.监控二叉树 | Binary Tree Cameras

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...

  10. 由任意二叉树的前序遍历序列和中序遍历序列求二叉树的思想方法_算法与数据结构基础 - 二叉树(Binary Tree)...

    二叉树基础 满足这样性质的树称为二叉树:空树或节点最多有两个子树,称为左子树.右子树, 左右子树节点同样最多有两个子树. 二叉树是递归定义的,因而常用递归/DFS的思想处理二叉树相关问题,例如Leet ...

最新文章

  1. Android 手把手教您自定义ViewGroup
  2. 每天一道LeetCode-----将链表每k个节点逆序一次
  3. 线性共轭梯度法python_python实现的共轭梯度法
  4. HDU5688 Problem D【字符串排序+MAP】
  5. CDH(Cloudera)与hadoop(apache)对比
  6. 实战HTML:模仿百度地图制作项目首页
  7. Python basemap模拟导弹发射
  8. InvalidArchiveError(‘Error with archive D:\\Program Files\\Anaconda\\pkgs\\numpy-base-1.19.1-py36ha3
  9. 细说文件读写操作(读写锁)
  10. 黑马程序员-说说自己
  11. 在ArcCatalog中建立空间数据库以及数据的编辑
  12. 树莓派——4G网卡华为ME909s-821 4G上网及开机自启动(1)
  13. 【3D音效增强神器】Boom 3D for Mac中文版 v1.2.2
  14. stm32采集脉冲信号_stm32用ETR采集外部脉冲个数出现二分频问题,请教哪里设置......
  15. 【2019年02月11日】股息率分红最高排名
  16. poj 2683 Ohgas' Fortune 利率计算
  17. int类型与char类型
  18. Centos6.6下编译安装Apache2.2.31
  19. MSN, 迅雷等调用小红伞作为杀毒软件的方法
  20. 已解决selenium.common.exceptions.WebDriverException: Message: unknown error: cannot find Chrome binary

热门文章

  1. adb 操作 快速点击屏幕
  2. 战略到底在研究什么?
  3. 如何成为优秀的工作者
  4. 【neutron】OpenStack Neutron -- 学习资料
  5. Windows系统深度学习Anaconda、PyTorch软件安装教程
  6. 能力不够,你就态度好点
  7. 基于Logistic混沌序列和DNA编码的图像加解密算法仿真
  8. Galera Cluster一致性问题
  9. mysql:增删改查语句大全
  10. VC++常用功能开发