精华内容
下载资源
问答
  • 的父亲数组表示法

    千次阅读 2006-05-04 16:29:00
    设T是一棵树,表示T的一种最简单的方法是用一个一维数组存储每个结点数组的下标就是结点的位置指针,每个结点中有一个指向各自的父亲结点数组下标的域,这样可使Parent操作非常方便。类型定义如下: Type ...

    设T是一棵树,表示T的一种最简单的方法是用一个一维数组存储每个结点,数组的下标就是结点的位置指针,每个结点中有一个指向各自的父亲结点的数组下标的域,这样可使Parent操作非常方便。类型定义如下:

    Type

    TPosition=integer; {结点的位置类型为整型}

     NodeType=Record

               Label:LabelType;    {该结点的标号}

               Parent:TPosition;   {该结点的父亲的数组下标,对于根结点该域为0}

              End;

     TreeType=Record

              NodeCount:integer;  {树的结点的总数目}

              Node:Array [1..MaxNodeCount] of NodeType;{存储树的结点}

              End;

    由于树中每个结点的父亲是唯一的,所以上述的父亲数组表示法可以唯一地表示任何一棵树。在这种表示法下,寻找一个结点的父结点只需要O(1)时间。在树中可以从一个结点出发找出一条向上延伸到达其祖先的道路,即从一个结点到其父亲,再到其祖父等等。求这样的道路所需的时间正比于道路上结点的个数。在树的父亲数组表示法中,对于涉及查询儿子和兄弟信息的树操作,可能要遍历整个数组。为了节省查询时间,可以规定指示儿子的数组下标值大于父亲的数组下标值,而指示兄弟结点的数组下标值随着兄弟的从左到右是递增的。

    父亲数组实现的ADT树操作

    函数 Parent(v,T)

    功能

    这是一个求父结点的函数,函数值为树T中标号为v的结点的父亲。当v是根结点时,函数值为0,表示结点v没有父结点。

    实现

    Function Parent(v:TPosition;var T:TreeType):TPosition;

    begin

     return(T.Node[v].Parent);

    end;

    说明

    由于每个结点都有一个域存储了其父亲结点的标号(数组下标),因此Parent操作实现非常简单。

    复杂性

    显然为O(1)。

    函数 Leftmost_Child(v,T)

    功能

    这是一个求最左儿子结点的函数。函数值为树T中标号为v的结点的最左儿子。当v是叶结点时,函数值为0,表示结点v没有儿子。

    实现

    Function Leftmost_Child(v:TPosition;var  T:TreeType):TPosition;

    begin

     i:=v+1;

     while (i<=T.NodeCount)and(T.Node[i].Parent<>v) do  inc(i);

     if i=T.NodeCount+1 then return(0)

                                                 else return(i);

    end;

    说明

    因为没有保存每个结点的子结点的信息,因此只能依次扫描每个结点,根据我们的约定,子结点一定排在父结点的后面,且兄弟结点的下标从左到右依次递增,因此第一次遇到的父亲是n的结点就是n的最左结点。

    复杂性

    该算法的复杂性取决于while循环。若设T.NodeCount=n,显然,在最坏情况下循环执行n-v次,最好情况下执行1次,平均情况下执行(n-v)/2,所以无论何种情况下,复杂性都为O(n)。

    函数 Right_Sibling(v,T)

    功能

    这是一个求右邻兄弟的函数,函数值为树T中结点v的右邻兄弟。当v没有右邻兄弟时,函数值为0。

    实现

    Function Right_Sibling(v:TPosition;var  T:TreeType):TPosition;

    begin

     i:=v+1;

     while (i<=T.NodeCount)and(T.Node[i].Parent<>T.Node[v].Parent) do

         inc(i);

     if i=T.NodeCount+1 then return(0)

                                                 else return(i);

    end;

    说明

    依次搜索排在v之后的结点,遇到第一个与v有相同父结点的结点就是v的右邻兄弟。

    复杂性

    同Leftmost_Child一样,该函数复杂性为O(n),其中n为树的总结点数。

    函数 Create(i,x,T1,T2,..,Ti)

    功能

    这是一族建树过程。对于每一个非负整数i,该函数生成一棵新树T,T的根结点是标号为x的新结点v,并令v有i个儿子,这些儿子从左到右分别为树T1,T2,..,Ti的根。当i=0时,v既是树根,又是树叶。

    实现

    Procedure Create(i:integer;var x:LabelType;var T1,T2,..,Ti,T:TreeType);

    var

    k,j,father:integer;

    begin

     with T do

     begin

     NodeCount:=1;

     Node[1].Label:=x;

     Node[1].Parent:=0;  {生成根结点}

     for k:=1 to i do

      if Tk.NodeCount<>0 then

      begin

       inc(NodeCount);

       Node[NodeCount]:=Tk.Node[1];

       Node[NodeCount].Parent:=1;{修改Tk的根结点的父亲使其指向T的根}

       father:=NodeCount;  {记下Tk的根结点的标号}

       for j:=2 to Tk.NodeCount do

        beign

        inc(NodeCount);

        Node[NodeCount]:=Tk.Node[j];

        Node[NodeCount].Parent:=Node[NodeCount].Parent+father-1;

          {修改Tk的每一个非根结点的父亲,因为Tk的根结点的位置改变了}

        end;    

      end;

      end;

    end;

    说明

    这个过程首先生成一个新结点,其中存储的数据为x,新结点在数组T的第一个元素位置上;然后对于每一个Tk,1≤k≤i,如果Tk不为空则将Tk的每一个结点复制到T中,同时修改Tk的每一个元素的父结点,因为Tk的根结点在T中的下标已经不是1了,而是father,因此Tk的每一个元素的父结点的下标都应给增加一个增量father-1。

    复杂性

    如果∑(Tk的结点数)=n,即生成的新树的结点总数为n,则复杂性为O(n)。

    Label,Root和MakeNull比较简单,这里就不一一实现了。

    我们可以看出,用父亲数组实现树,比较容易实现Parent运算,但是对于Leftmost_Child和Right_Sibling则效率不高,而且这种实现方法很占用内存。但实现上比较简单。

    <script src="../../../lib/footer.js" type="text/javascript"> </script>
    展开全文
  • 已知一棵树的层次序列以及每个结点的度,编写算法构造此树的孩子兄弟链表 算法思想:已知先序遍历以及结点度数我们只需要编写代码给每一个除根结以外的结点寻找他们的兄弟和孩子(利用度数寻找孩子与兄弟,利用层次...

    已知一棵树的层次序列以及每个结点的度,编写算法构造此树的孩子兄弟链表

    算法思想:已知先序遍历以及结点度数我们只需要编写代码给每一个除根结以外的结点寻找他们的兄弟和孩子(利用度数寻找孩子与兄弟,利用层次遍历构造辅助数组)详见代码


    void createCSTree_Degree(CSTree *&T,int data[],int degree[],int n){
    
    	CSTree **temp=(CSTree**)malloc(sizeof(CSTree)*n); //创建临时数组
    	for(int i=0;i<n;i++){  //把每一个节点放进临时数组
    		temp[i]=(CSTree*)malloc(sizeof(CSTree));
    		temp[i]->data=data[i];
    		temp[i]->lchild=temp[i]->sright=NULL; //初始化兄弟与孩子结点
    			
    	}
    	//构造完临时数组之后我们得到了先序序列的结点数组接下来我们根据结点的度来确定每一个结点的儿子与儿子的兄弟结点
    	int index=1; //指向数组还未操作的结点 默认根节点已经被操作了
    	int d;//d表示当前结点的度数;
    	for(int j=0;j<n;j++){
    		d=degree[j];   //获取当前结点的度数
    
    		//接下来找他的儿子与儿子兄弟
    
    		//首先要知道叶子结点的是没有兄弟和孩子的所以先进行一个判断  注:叶子结点的度数为0
    
    		if(d){  //若不是叶子结点 开始找儿子 
    			temp[j]->lchild=temp[index];  //首先找到第一个儿子结点
    			
    			for(int k=2;k<=d;k++){  //然后给第一个儿子结点找兄弟结点 注意 k=2 表示的是 从第二个孩子开始 一共有 d孩子 d是度数
    				index++;
    				temp[index-1]->sright=temp[index]; //index -1 为上一个孩子结点也就是 父节点的第一个孩子/或者是上一个孩子的兄弟 剩下的孩子结点依次是上一个孩子的右兄弟
    			}
    		}
    
    	}
    	//找完所有孩子结点与孩子的兄弟结点后就返回头指针 //注意这里是函数参数返回的
    	T=*temp;
    }
    
    

    构造过程大概就是这样
    在这里插入图片描述

    展开全文
  • 线段 什么是线段 先说一下什么是线段吧 ...而线段,就是一棵由线段构成的二叉树,每个结点都代表一条线段 [a,b](也就是我们前面说的一串变量)。非叶子的结点所对应的线段都有两个子结点,左儿...

    线段树

    什么是线段树

    先说一下什么是线段树吧
    大家都知道,初中课本中对于线的定义:

    点动成线

    那么就是说一条线段可以分成若干个点,再想想我们最常用的一维数组,构成数组的是一个个的变量,如果把变量看成一个个点,那么数组就是一条线了!
    而线段树,就是一棵由线段构成的二叉树,每个结点都代表一条线段 [a,b](也就是我们前面说的一串变量)。非叶子的结点所对应的线段都有两个子结点,左儿子代表的线段为 [a,(a+b)/2],右儿子代表的线段为 [((a+b)/2)+1,b]。使用线段树这一数据结构,可以查找一个连续区间中节点的信息,也可以修改一个连续区间中结点的信息。
    那么为什么不用普通的数组而是把数组上又加了”坨”树呢?

    想想我们当是为什么要学习链表这个数据结构,因为数组对于元素的添加与删除效率太低!而线段树也是为了解决这个问题的所以线段树的作用是:

    优化区间操作的复杂度。

    如图这就是一个线段树(建议自己根据定义自己画一下)

    这里写图片描述

    线段树的单点更新

    这一小节我们先看单点更新
    顾名思义,单点更新就是只更新一个叶子节点啦
    线段树这一部分函数的参数比较多注意区分!
    我们先看两个基础的操作

    1.修改

    就是将数据改了呗,可以使加减或者是覆盖,这个的话,具体实现的时候稍微改一下即可!
    上代码(时间复杂度:O(logN)可以从这里看出其高效性)

    void up(int p){
        s[p]=s[p*2]+s[p*2+1];
    }
    
    void modify(int p,int l,int r,int x,int v){
        if(l==r){
            s[p]+=v;
            return;
        }    
        int mid=(l+r)/2;
        if(x<=mid){
            modify(p*2,l,mid,x,v);
        }else {
            modify(p*2+1,mid+1,r,x,v);    
        }
        up(p);
    }

    说明:
    1.网上有两种代码,一种没有up…但是大多数人的都有,于是我就用了有up的了。
    2.up函数作用:把儿子结点的信息更新到父亲结点
    3.molify函数:这个就是修改函数啦,说一下变量
    –1.p:表示当前位置的节点编号,例如我们在一开始是要在全局进行修改,于是就把p定为根节点。随着修改的进行,我们要修改p来到达其他节点,例如从a节点到a的右孩子就是:p=P*2+1,就像我们平时用的cur一样。
    –2.l和r:l和r表示的是当前锁定的区间的范围,例如刚开始l=1,r=n,就是说范围在[1,n]上(也就是全局),但是我发现目标在根的左孩子上,那么我就要更改l,r为l=l,r=(l+r)/2了。
    –3.x:就是要更改的节点编号
    –4.v:要更改的值

    注意:一定要自己走一遍!!!

    2.查询:

    就是查询区间内节点的值

    int query(int p,int l,int r,int x,int y){
        if(x<=l&&r<=y){
            return s[p];
        }
        int mid=(l+r)/2,res=0;
        if(x<=mid){
            res+=query(p*2,l,mid,x,y);
        }
        if(y>mid){
            res+=query(p*2+1,mid+1,r,x,y);
        }
        return res;
    }

    说明:
    –1.p和上面一样
    –2.l,r和上面一样是当前锁定的节点范围,一定要注意!!!!
    –3.x,y是我要查询的区间,这个在就是调用函数的时候说明的区间,不变!!!,注意区别与l,r的关系!!!

    3.建树

    为什么最后说这个?
    因为我学的时候这就不是一个模块
    只需要注意建的树s[]的数组必须开四倍空间!!!

    至此所有的单点更新内容全部结束!
    给出模板代码:

    #include <iostream>
    using namespace std;
    const int MAX_N=10010;
    int s[4*MAX_N];
    
    void up(int p){
        s[p]=s[p*2]+s[p*2+1];
    }
    
    void modify(int p,int l,int r,int x,int v){
        if(l==r){
            s[p]+=v;
            return;
        }    
        int mid=(l+r)/2;
        if(x<=mid){
            modify(p*2,l,mid,x,v);
        }else {
            modify(p*2+1,mid+1,r,x,v);    
        }
        up(p);
    }
    
    int query(int p,int l,int r,int x,int y){
        if(x<=l&&r<=y){
            return s[p];
        }
        int mid=(l+r)/2,res=0;
        if(x<=mid){
            res+=query(p*2,l,mid,x,y);
        }
        if(y>mid){
            res+=query(p*2+1,mid+1,r,x,y);
        }
        return res;
    }
    
    int main() {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++){
            int d;
            cin>>d;
            modify(1,1,n,i,d);
        }
        int q;
        cin>>q;
        while(q--){
            int d,x,y;
            cin>>d>>x>>y;
            if(d==0){
                modify(1,1,n,x,y);
            }else{
                cout<<query(1,1,n,x,y)<<endl;
            }
        }
        return 0;
    }

    线段树的区间更新

    还是顾名思义,线段树的区间更新就是把段的数据统一更新了。
    当然我们可以反复执行单点更新的molify实现,但是效率呢?
    线段树的特点就是牺牲空间换时间,例如:
    我要反复执行[1,1000]区间赋值为1,再赋值为2,再赋值为1,再赋值为2…往复循环,那还不如memset高效呢!
    所以我们不能像单点更新一样言听计从了,有时候也要皮一下,于是我们有了lazy标记,什么意思呢,你让我把[1,1000]更新为1,我说好的,然后打一个标记到[1,1000]的子树的根节点上写上改为1000,但是我没有把根节点的子节点的数据改了,除非你来访问了,你访问多少,我打多少,你不访问,程序结束的时候我可能都没去真正的赋值!
    同样类似的标记命名还有col等,以下代码为col的。这里直接上模板代码了,函数名与单点的一样,参数略有不同,自己想。

    #include <iostream>
    using namespace std;
    const int MAX_N=10010;
    int s[4*MAX_N],col[4*MAX_N];
    
    void up(int p){
        s[p]=s[p*2]+s[p*2+1];
    }
    
    void down(int p,int l,int r){
        if(col[p]){
            int mid=(l+r)/2;
            s[p*2]+=col[p]*(mid-l+1);
            s[p*2+1]+=col[p]*(r-mid);
            col[p*2]+=col[p];
            col[p*2+1]+=col[p];
            col[p]=0;
        }
    }
    
    void modify(int p, int l, int r, int x, int y, int c) {
        if (x <= l && r <= y) {
            s[p] += (r - l + 1) * c;
            col[p] += c;
            return;
        }
        down(p, l, r);
        int mid = (l + r) / 2;
        if (x <= mid) {
            modify(p * 2, l, mid, x, y, c);
        }
        if (y > mid) {
            modify(p * 2 + 1, mid + 1, r, x, y, c);
        }
        up(p);
    }
    
    int query(int p, int l, int r, int x, int y) {
        if (x <= l && r <= y) {
            return s[p];
        }
        down(p, l, r);
        int mid = (l + r) / 2, res = 0;
        if (x <= mid) {
            res += query(p * 2, l, mid, x, y);
        }
        if (y > mid) {
            res += query(p * 2 + 1, mid + 1, r, x, y);
        }
        return res;
    }
    
    int main() {
        int n;
        cin>>n;
        for (int i = 1; i <= n; ++i) {
        int d;
        cin >> d;
        modify(1, 1, n, i, i, d);
        }
        int q;
        cin>>q;
        while (q--) {
        int d, x, y, c;
        cin >> d >> x >> y;
        if (d == 0) {
            cin >> c;
            modify(1, 1, n, x, y, c);
        } else {
            cout << query(1, 1, n, x, y) << endl;
            }   
        }
        return 0;
    }
    展开全文
  • 给定一个递增有序数组,要求构建一棵具有最小高度的二叉查找  题意:给定一个有序整数数组,元素各不相同且按照升序排列,让编写一个算法,创建一个高度最小的二叉查找 二叉查找定义:对于任意一个...
     给定一个递增有序数组,要求构建一棵具有最小高度的二叉查找树 

    题意:给定一个有序整数数组,元素各不相同且按照升序排列,让编写一个算法,创建一个高度最小的二叉查找树

    二叉查找树定义:对于任意一个结点,左边的结点均小于它,右边的结点均大于它


    思路:要创建一个高度最小的树,就必须让左右子结点的数量越接近越好,也就是说,要让中间值成为根节点,这样,左边的一半是左子树,右边的一半是右子树。然后,继续以类似的方式构造整棵树,数据每一段的中间值成为根元素,左边一半成为左子树,右边一半成为右子树。

    递归实现如下:

    #include <iostream>
    #include<vector>
    using namespace std;
    
    struct TreeNode
    {
    	int val;
    	TreeNode* left;
    	TreeNode* right;
    	TreeNode(int x) :val(x), left(NULL), right(NULL) {}
    };
    
    class Solution {
    public:
    	TreeNode* CreateMinnumTree(vector<int> &arr, int start, int end)
    	{
    		if (start > end)
    			return NULL;
    		if (start == end) {
    			TreeNode* root = new TreeNode(arr[start]);
    			return root;
    		}
    		int mid = (start + end) / 2;
    		TreeNode* root = new TreeNode(arr[mid]);
    		root->left = CreateMinnumTree(arr, start, mid - 1);
    		root->right = CreateMinnumTree(arr, mid + 1, end);
    		return root;
    	}
    
    	TreeNode* CreateMinnumBSTree(vector<int>& arr) {
    		if (arr.empty())
    			return NULL;
    		return CreateMinnumTree(arr, 0, arr.size() - 1);
    	}
    };
    
    void preOrder(TreeNode* root) {
    	if (root != NULL)
    	{
    		cout << root->val << " ";
    		preOrder(root->left);
    		preOrder(root->right);
    	}
    }
    
    int main()
    {
    	vector<int> arr = { 1,2,3,4,5,6,7 };
    	Solution s;
    	TreeNode* root = s.CreateMinnumBSTree(arr);
    
    	preOrder(root);
    	return 0;
    }
    
    


    展开全文
  • //③ 将一棵二叉树的所有结点存储在一维数组中,虚结点用#表示, //利用二叉树的性质5,建立二叉树的二叉链表。 //例如用数组a存储的二叉树的结点如下(0单元不用): CQueue Q; int Qn[MAX],f,r,i; BiTree p; ...
  • 线段,树状数组

    千次阅读 2013-04-09 20:18:17
    线段一棵二叉树,中的每一个结点表示了一个区间[a,b]。每一个叶子节点表示了一个单位区间。对于每一个非叶结点所表示的结点[a,b],其左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2,b]。  例如...
  • 给定一个递增有序数组,要求构建一棵具有最小高度的二叉查找  题意:给定一个有序整数数组,元素各不相同且按照升序排列,让编写一个算法,创建一个高度最小的二叉查找 二叉查找定义:对于任意...
  • 寻找一棵树任意两个结点的公共节点思路: 创建树结点的结构:1、数据 2、其节点所在位置 创建容纳整棵树的结构:1、树的所有结点 2、结点数 创建树:通过循环,给整棵树每个结点赋值,并记录其节点所在位置...
  • 目录 1.线段 2.树状数组 3.代码实现 4.例题 ...线段 ... 线段也可与称为区间 ... 线段同时也是一个二叉树 ...总结:线段一棵二叉树,中的每一个结 点表示了一个区间[a,b]。a,b通常是整数。 每一个叶子...
  • 节点表示法表示一棵树

    千次阅读 2014-03-09 16:32:49
    今天学习,把书上的代码自己边对照,边敲了一下。 package mytree; ... * 用节点表示法表示一棵树。 * * @author lirui * @param */ public class TreeParent { public static class No
  • BIT二叉索引(树状数组

    千次阅读 2016-12-16 20:36:56
    本文介绍BIT二叉索引这种数据结构的搭建和应用。该数据结构能在动态修改的数组连续和查询问题上有极其出色的表现。 POWERED BY PHANTOM_LSH 本文知识和代码(c++)风格来源于刘汝佳的《算法竞赛入门经典 训练指南...
  • 输入一棵二叉搜索,将该二叉搜索转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整结点指针的指向。 解题思路: 最后得到的链表是一个双向链表 而二叉排序的中序遍历得到的就是一个有序的...
  • 根据Push和Pop来不用建树,输出先序、中序、后序遍历数组的问题。很好地利用了遍历的特性,采用了“分而治之”的递归思想。
  • 弹出结点,每轮递归返回到父结点时,当前路径也应该回退结点(回溯法)。 */ class Solution { public: vector&lt;vector&lt;int&gt; &gt; FindPath(TreeNode* root,int e...
  • 二叉搜索:二叉查找(Binary Search Tree),(又:二叉搜索,二叉排序)它或者是一棵,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子不...
  • 】二叉搜索的第k个结点
  • 二叉排序一棵二叉树,且具有以下性质:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子不空,则右子上所有结点的值均大于它的根结点的值; 它的左、右子也分别为二叉排序。...
  • 如果要从一个有序数组中选择一个元素作为根结点,应该选择哪个元素呢?我们应该选择有序数组的...由上面的思路,我们可以在O(N)的时间内从有序数组创建一棵平衡的BST,使用分治算法,代码如下: struct node* sorted
  • //右子长度 if ( llen > 0 ) root - > left = creat ( A , B , l1 + 1 , l1 + llen , l2 , llen + l2 - 1 ) ; else root - > left = NULL ; if ( rlen > 0 ) root - > right = creat ...
  • --二叉树的数组实现

    千次阅读 2016-09-04 16:04:47
    树--二叉树的数组实现 简要介绍: 树是节点的有限集合 度:当前结点的子节点的数量 叶子:(终端节点) 根:(非终端节点) 有序数:子节点不能互换顺序 ...森林:多颗独立的树,一棵树看成由不同的子树,也是森林
  • * Content:合并两个二叉排序(二叉查找)到数组中 * @author tangzhenyu * Specialty:不修改原始的那两个二叉排序,以中序遍历顺序遍历两颗二叉排序,排序运用的是归并排序的思想。
  • 败者 和 胜者---数组实现

    千次阅读 2012-11-30 01:39:12
    胜者和败者都是完全二叉树,是形选择排序的种变型。每个叶子结点相当于个选手,每个中间结点相当于场比赛,每层相当于轮比赛。  不同的是,胜者的中间结点记录的是胜者的标号;而败者的中间...
  • 给定一个有序数组(递增),写程序构建一棵具有最小高度的二叉树。 想要使构建出来的二叉树高度最小,那么对于任意结点, 它的左子树和右子结点数量应该相当。比如,当我们将一个数放在根结点, 那么理想情况是,...
  • 一棵后缀包含一个指定文本的所有后缀,对于在一个长度为N的文本中查找一个长度为M的子字符串,一个后缀仅仅需要M次比较,而这个比较次数是查找该字符串所需要的最小比较次数。 后缀有以下特征:一条边可以...
  • 采用孩子兄弟表示法建立一棵树

    千次阅读 2020-05-24 11:22:10
    采用孩子兄弟表示法建立一棵树。 说明:因为孩子兄弟表示法的特点,不好用递归创建,所以利用队列来存放结构体。 注意:当指针作为函数参数时,不能改变实参指针的指向,只能改变实参指针所指向的数据 #include&...
  • 数组

    2017-08-28 21:39:46
    对于一个没有重复元素的整数数组,请用其中元素构造一棵MaxTree,MaxTree定义为一棵二叉树,其中的节点与数组元素一一对应,同时对于MaxTree的每棵子树,它的根的元素值为子树的最大值。现有一建树方法,对于数组中...
  • 在哈夫曼中,没有度为1的结点结点总数是n0+n2(其中n0表示二叉树中度为0的结点数,n2表示度为2的结点数),而由二叉树的性质知道n0=n2+1,所以一棵哈夫曼结点总数是2n0-1。 由此可以得出:任何n个字符的...
  • 它或者是一棵,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子不空,则右子上所有结点的值均大于它的根结点的值; 它的左、右子也分别为二叉...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 44,537
精华内容 17,814
关键字:

一棵树的父结点数组