二叉树(Binary Tree)是n(n>=0)个结点的有限集合,该集合或者为空集(空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。node
每一个结点最多有两棵子树,因此二叉树中不存在度大于2的结点。二叉树中每个节点都是一个对象,每个数据节点都有三个指针,分别是指向父母、左孩子和右孩子的指针。每个节点都是经过指针相互链接的。相连指针的关系都是父子关系。算法
二叉树节点定义以下:数组
struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; };
空二叉树 只有一个根结点 根结点只有左子树 根结点只有右子树 根结点既有左子树又有右子树
拥有三个结点的普通树只有两种状况:两层或者三层。但因为二叉树要区分左右,因此就会演变成以下的五种形态:post
如上面倒数第一副图的第二、3小图所示。this
在一棵二叉树中,若是全部分支结点都存在左子树和右子树,而且全部叶子都在同一层上,这样的二叉树称为满二叉树。以下图所示:spa
彻底二叉树是指最后一层左边是满的,右边可能满也可能不满,而后其他层都是满的。一个深度为k,节点个数为 2^k - 1 的二叉树为满二叉树(彻底二叉树)。就是一棵树,深度为k,而且没有空位。.net
彻底二叉树的特色有:设计
叶子结点只能出如今最下两层。 最下层的叶子必定集中在左部连续位置。 倒数第二层,如有叶子结点,必定都在右部连续位置。 若是结点度为1,则该结点只有左孩子。 一样结点树的二叉树,彻底二叉树的深度最小。
注意:满二叉树必定是彻底二叉树,但彻底二叉树不必定是满二叉树。3d
算法以下:指针
bool is_complete(tree *root) { queue q; tree *ptr; // 进行广度优先遍历(层次遍历),并把NULL节点也放入队列 q.push(root); while ((ptr = q.pop()) != NULL) { q.push(ptr->left); q.push(ptr->right); } // 判断是否还有未被访问到的节点 while (!q.is_empty()) { ptr = q.pop(); // 有未访问到的的非NULL节点,则树存在空洞,为非彻底二叉树 if (NULL != ptr) { return false; } } return true; }
二叉树的性质一:在二叉树的第i层上至多有2^(i-1)个结点(i>=1)
二叉树的性质二:深度为k的二叉树至多有2^k-1个结点(k>=1)
二叉树的顺序存储结构就是用一维数组存储二叉树中的各个结点,而且结点的存储位置能体现结点之间的逻辑关系。
既然顺序存储方式的适用性不强,那么咱们就要考虑链式存储结构啦。二叉树的存储按照国际惯例来讲通常也是采用链式存储结构的。
二叉树每一个结点最多有两个孩子,因此为它设计一个数据域和两个指针域是比较天然的想法,咱们称这样的链表叫作二叉链表。
二叉树的遍历(traversing binary tree)是指从根结点出发,按照某种次序依次访问二叉树中全部结点,使得每一个结点被访问一次且仅被访问一次。
二叉树的遍历有三种方式,以下:
(1)前序遍历(DLR),首先访问根结点,而后遍历左子树,最后遍历右子树。简记根-左-右。 (2)中序遍历(LDR),首先遍历左子树,而后访问根结点,最后遍历右子树。简记左-根-右。 (3)后序遍历(LRD),首先遍历左子树,而后遍历右子树,最后访问根结点。简记左-右-根。
若二叉树为空,则空操做返回,不然先访问根结点,而后前序遍历左子树,再前序遍历右子树。
遍历的顺序为:A B D H I E J C F K G
//先序遍历 function preOrder(node){ if(!node == null){ putstr(node.show()+ " "); preOrder(node.left); preOrder(node.right); } }
若树为空,则空操做返回,不然从根结点开始(注意并非先访问根结点),中序遍历根结点的左子树,而后是访问根结点,最后中序遍历右子树。
遍历的顺序为:H D I B E J A F K C G
//使用递归方式实现中序遍历 function inOrder(node){ if(!(node == null)){ inOrder(node.left);//先访问左子树 putstr(node.show()+ " ");//再访问根节点 inOrder(node.right);//最后访问右子树 } }
若树为空,则空操做返回,不然从左到右先叶子后结点的方式遍历访问左右子树,最后访问根结点。
遍历的顺序为:H I D J E B K F G C A
//后序遍历 function postOrder(node){ if(!node == null){ postOrder(node.left); postOrder(node.right); putStr(node.show()+ " "); } }
二叉查找树(BST)由节点组成,因此咱们定义一个Node
节点对象以下:
function Node(data,left,right){ this.data = data; this.left = left;//保存left节点连接 this.right = right; this.show = show; } function show(){ return this.data;//显示保存在节点中的数据 }
查找BST上的最小值和最大值很是简单,由于较小的值老是在左子节点上,在BST上查找最小值,只需遍历左子树,直到找到最后一个节点
function getMin(){ var current = this.root; while(!(current.left == null)){ current = current.left; } return current.data; }
该方法沿着BST的左子树挨个遍历,直到遍历到BST最左的节点,该节点被定义为:
current.left = null;
这时,当前节点上保存的值就是最小值
在BST上查找最大值只须要遍历右子树,直到找到最后一个节点,该节点上保存的值就是最大值。
function getMax(){ var current = this.root; while(!(current.right == null)){ current = current.right; } return current.data; }
二叉树相关题目:http://blog.csdn.net/luckyxiaoqiang/article/details/7518888