数据结构之树

一、树的概念

树是一种非线性结构的有限集合。由n(n>=0)个节点组成。
如果n=0,是一棵空树。
如果n>0,说明至少有一个节点,这样的树有一个特殊的节点,这个节点没有父节点,称之为根节点(root)。
除根节点之外的节点又有m个互不相交的集合。其中每一个集合本身也是一棵树,称之为原树的子树。
在这里插入图片描述
节点:
每一片树叶就是一个节点,每个节点包含数据项,和指向其他节点的指针,如上图一共有11个节点。

节点的度:
节点所拥有的子树的数量。比如节点1就有3个度,分别为2,3,4;节点2就有2个度,分别为5,6;节点3只有一个度,为7;节点4也有3个度,分别为8,9,10;节点6也有一个度,为11。没有子树的度为0。

叶节点:
度为0的节点被成为叶节点。比如5,7,8,9,10,11。

分支节点:
除叶节点外的节点就是分支节点。比如1,2,3,4,6。

子女节点:
若一个节点有子树,那么子树就是这个节点的子女节点。比如2,3,4就是1的子女节点。

父节点:
与子女节点对应,若一个节点有子树,那么这个节点就是所有子树的父节点。比如1就是2,3,4的父节点。

兄弟节点:
同一个父节点的子女节点称为兄弟节点。

祖先节点:
从根节点到某节点上经过的所有节点都称为祖先节点,比如节点11的祖先节点就是1,2,6,11。

子孙节点:
某一个节点的子女节点,以及该节点的节点的子女节点,都是该节点的子女节点。比如对于节点2来说,节点5,6,11都是它的子孙节点。

节点所在层次:
在同一个水平线上的节点也在同一层。比如以上的树就有4层。节点1在第一层;节点2,3,4在第二层;节点5,6,7,8,9,10在第三层;节点11在第四层。

树的深度:
一棵树中距离根节点最远节点所在的层次就是树的深度。其实也就是一棵树有多少层就是一棵树的深度。本例中的树的深度为4。

树的高度:
叶节点(没有子女节点)的高度为1,非叶节点的高度是它子女节点高度的最大值+1,高度与深度数值相等。计算方式不一样。

树的度:
一棵树中节点的最大值。如本例中所有节点的最大值是3,树的度就是3。

有序树:
一棵树中,各个子树的节点是有次序的,第一颗树节点1,第二颗是节点2,就叫做有序树。

无序树:
跟有序树正好相反,树中节点的次序不是有序的,可以互换位置,叫做无序树。

森林:
森林是m(m>=0)棵树的集合。

二、二叉树

二叉树是一棵特殊的树,它的特征之一是一个节点最多有2个子女节点。如果有2个节点,称为左子女和右子女,且次序不能颠倒。每一层都到达了最大数量节点的二叉树为满二叉树,也就是每个节点都有左右两个子女节点。第k层,或是满的或是从右向左连续缺若干个节点称为完全二叉树。

三、二叉树的方法

  1. 树的创建 createTree 方法;
  2. 树的销毁 destroy 方法;
  3. 遍历树 treeTraverse 方法;
  4. 查找节点 searchNode 方法;
  5. 插入节点 addNode 方法;
  6. 删除节点 deleteNode 方法。

四、二叉树的实现

如下图,通过数组来实现二叉树(蓝色的表示索引值)。
父节点索引值 * 2+1=左子女节点索引值;
父节点索引值 * 2+2=右子女节点索引值;
比如,节点9的索引为1,
左子女节点12索引值=1 * 2+1=3;
右子女节点25索引值=1 * 2+2=4;
在这里插入图片描述

    //构造函数
    function Tree(size) {
        var tree = [6];
        for(var i = 1;i<size;i++){
            tree[i] = 0;
        }
        //销毁树
        this.destroy = function() {
            tree = null;
        };
        //搜索节点
        this.searchNode = function (index) {
            if(index<0 || index>=size){
               return null;
            };
            if(tree[index] == 0){
                return null;
            }
            return tree[index];
        };
        //添加节点
        this.addNode = function (index,direction,node) {
            if(index<0 || index>=size){
                return false;
            };
            if(tree[index] == 0){
                return false;
            };
            if(direction == 1){
                if(index*2+1>=size){
                    return false;
                };
                if(tree[index*2+1] != 0){
                    return false;
                };
                tree[index*2+1] = node;
            };
            if(direction == 2){
                if(index*2+2>=size){
                    return false;
                };
                if(tree[index*2+2] != 0){
                    return false;
                };
                tree[index*2+2] = node;
            };
            return true;
        };
        //删除节点
        this.deleteNode = function (index) {
            if(index<0 || index>=size){
                return null;
            };
            if(tree[index] == 0){
                return null;
            }
            tree[index] = 0;
            return true;
        };
        //遍历节点
        this.treeTraverse = function () {
            for(var i=0;i<size;i++){
                console.log(tree[i]);
            }
        }
    }
    var tree = new Tree(7);
    tree.addNode(0,1,9);
    tree.addNode(0,2,10);
    tree.addNode(1,1,12);
    tree.addNode(1,2,25);
    tree.addNode(2,1,12);
    tree.addNode(2,2,18);
    tree.treeTraverse();

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值