树与二叉树
一、基本概念
1. 树的定义
树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。
具有以下的特点:
(01) 每个节点有零个或多个子节点;
(02) 没有父节点的节点称为根节点;
(03) 每一个非根节点有且只有一个父节点;
(04) 除了根节点外,每个子节点可以分为多个不相交的子树。
2. 二叉树的定义
二叉树是每个节点最多有两个子树的树结构。它有五种基本形态:二叉树可以是空集;根可以有空的左子树或右子树;或者左、右子树皆为空。
3. 满二叉树,完全二叉树和二叉查找树
1️⃣满二叉树
定义:高度为h,并且由2{h} –1个结点的二叉树,被称为满二叉树。
2️⃣完全二叉树
在一棵完全二叉树中,除最后一层之外,每一层都有在这一层上可能的最大节点数量。最后一层的节点数量可以小于最大可能数量,但是它们必须是从左到右一个一个挨着排列的。
二、二叉树的存储结构
1. 顺序存储结构
用一组连续的存储单元依次自上而下,自左至右存储完全二叉树上的结点元素,即将二叉树上编号为i的结点元素存储在加上定义的一维数组中下标为i-1的分量中。“0”表示不存在此结点。这种顺序存储结构仅适用于完全二叉树。
因为,在最坏情况下,一个深度为k且只有k个结点的单支树(树中不存在度为2的结点)却需要长度为2的n次方-1的一维数组。
2. 链式存储结构
二叉树的结点由一个数据元素和分别指向其左右子树的两个分支构成,则表示二叉树的链表中的结点至少包含三个域:数据域和左右指针域。有时,为了便于找到结点的双亲,则还可在结点结构中增加一个指向其双亲结点的指针域。利用这两种结构所得的二叉树的存储结构分别称之为二叉链表和三叉链表。
在含有n个结点的二叉链表中有n+1个空链域,我们可以利用这些空链域存储其他有用信息,从而得到另一种链式存储结构—线索链表。
// 顺序存储结构
var tree = [1, 2, 3, 4, 5, , 6, , , 7];
// 链式存储结构
function BinaryTree(data, leftChild, rightChild) {
this.data = data || null;
// 左右孩子结点
this.leftChild = leftChild || null;
this.rightChild = rightChild || null;
}
三、遍历二叉树
是指按指定的规律对二叉树中的每个结点访问一次且仅访问一次
二叉树的遍历主要分三种:
先(根)序遍历:根左右
中(根)序遍历:左根右
后(根)序遍历:左右根
四、代码实现
function BinaryTree(){
/*创建节点*/
var Node=function(key){
this.key=key;
this.left=null;
this.right=null;
}
/*插入根节点*/
var root=null;
this.insert=function(key){
var newNode=new Node(key);
if (root==null) {
root=newNode;
}else{
insertNode(root,newNode);
}
}
/*插入子节点*/
function insertNode(node,newNode){
if (newNode.key<node.key) {
if (node.left===null) {
console.log('left==='+newNode.key)
node.left=newNode;
}else{
insertNode(node.left,newNode);
}
}else{
if (node.right===null) {
console.log('right==='+newNode.key)
node.right=newNode;
}else{
insertNode(node.right,newNode);
}
}
}
/*前序遍历*/
this.preOrderTraverse = function(){
var preOrderTraverseNode = function(node,callback){
if (node!==null) {
callback(node.key);
preOrderTraverseNode(node.left,callback);
preOrderTraverseNode(node.right,callback);
}
}
preOrderTraverseNode(root,callback)
}
/*中序遍历*/
this.inOrderTraverse = function(callback){
var inOrderTraverseNode=function(node,callback){
if (node!==null) {
inOrderTraverseNode(node.left,callback);
callback(node.key);
inOrderTraverseNode(node.right,callback);
}
}
inOrderTraverseNode(root,callback);
}
/*后序遍历*/
this.postOrderTraverse = function(callback){
var postOrderTraverseNode=function(node,callback){
if (node!==null) {
postOrderTraverseNode(node.left,callback);
postOrderTraverseNode(node.right,callback);
callback(node.key);
}
}
postOrderTraverseNode(root,callback);
}
}
var nodes=[8,3,10,1,6,14,4,7,13];
var binaryTree=new BinaryTree();
nodes.forEach(function(key){
binaryTree.insert(key);
});
console.log('==================')
var callback=function(key){
console.log(key);
}
binaryTree.postOrderTraverse(callback);