赞
踩
GitHub同步更新(已分类):Data_Structure_And_Algorithm-Review
公众号:URLeisure 的复习仓库
公众号二维码见文末
以下是本篇文章正文内容,下面案例可供参考。
二叉树也可以采用顺序存储,按照完全二叉树的节点层次编号,依次存放二叉树中的数据元素。
完全二叉树很适合顺序存储方式,下图所示的完全二叉树的顺序存储结构如图所示。
二叉树最多有两个“叉”,即最多有两棵子树。
二叉树采用链式存储方式:
每个节点包含一个数据域,存储节点信息;还包含两个指针域,指向左右两个孩子。
一般情况下,二叉树采用二叉链表存储即可,但是在实际问题中,如果经常需要访问双亲节点,二叉链表存储则必须从根出发查找其双亲节点,这样做非常麻烦。
这时可以采用,三叉链表。
从二叉树的定义可以看出,它是递归定义的(除了根之外,左、右子树也是一棵二叉树),因此可以用递归来创建二叉树。
递归创建二叉树有两种方法,分别是询问法和补空法。
询问法是为了更好的理解二叉树创建的过程,要是直接复制代码去做题,hh。
每次输入节点信息后,询问是否创建该节点的左子树。
如果是,则递归创建其左子树,否则左子树为空。
询问是否创建该节点的右子树。
如果是,则递归创建其右子树,否则其右子为空
算法步骤
例如,输入下图二叉树。
是否添加B的左孩子?(Y/N) Y
请输入节点信息:D
输入后创建节点D,作为B的左孩子,如图。
是否添加D的左孩子?(Y/N) N
是否添加D的右孩子?(Y/N) N
输入后D的左右孩子均为空,如图。
是否添加B的右孩子?(Y/N) Y
请输入节点信息:E
输入后创建节点E,作为B的右孩子,如图。
是否添加E的左孩子?(Y/N) N
是否添加E的右孩子?(Y/N) N
输入后E的左右孩子均为空,如图。
是否添加A的右孩子?(Y/N) Y
请输入节点信息:C
输入后创建节点C,作为A的右孩子,如图。
是否添加C的左孩子?(Y/N) Y
请输入节点信息:F
输入后创建节点F,作为C的左孩子,如图。
是否添加F的左孩子?(Y/N) N
即F的左孩子为空,如图。
是否添加F的右孩子?(Y/N) Y
请输入节点信息:G
输入后创建节点G,作为F的左孩子,如图。
是否添加G的左孩子?(Y/N) N
是否添加G的右孩子?(Y/N) N
输入后G的左右孩子均为空,如图。
先创建一个结构体(内部类),包含数据域,和两个孩子指针域。
c++代码如下(示例):
typedef struct BNode{
char data;
BNode *lchild,*rchild;
}*Btree;
java代码如下(示例):
public static class BNode{
String data;
BNode lchild,rchild;
}
创建树
c++代码如下(示例):
void CreateTree(Btree &T){
char ch;
cout<<"请输入节点信息:"<<endl;
T = new BNode;
cin>>T->data;
cout<<"是否添加【"<<T->data<<"】的左孩子?(Y/N)"<<endl;
cin>>ch;
if(ch == 'Y'){
CreateTree(T->lchild);
}else{
T->lchild = NULL;
}
cout<<"是否添加【"<<T->data<<"】的右孩子?(Y/N)"<<endl;
cin>>ch;
if(ch == 'Y'){
CreateTree(T->rchild);
}else{
T->rchild = NULL;
}
}
java代码如下(示例):
public BNode createTree(BNode T){
String ch;
Scanner sc = new Scanner(System.in);
System.out.println("请输入节点信息:");
T = new BNode();
T.data= sc.nextLine();//用Scanner.nextLine()的时候一定要注意,换行输入
System.out.println("是否添加【"+T.data+"】的左孩子?(Y/N)");
ch = sc.nextLine();
if(ch.equals("Y")){
T.lchild = createTree(T.lchild);//跟c++的递归不太一样,注意java的递归“陷阱”
}else{
T.lchild = null;
}
System.out.println("是否添加【"+T.data+"】的右孩子?(Y/N)");
ch = sc.nextLine();
if(ch.equals("Y")){
T.rchild = createTree(T.rchild);//跟c++的递归不太一样,注意java的递归“陷阱”
}else{
T.rchild = null;
}
return T;
}
算法步骤
例如,输入下图二叉树。
输入为:(java中要换行输入)
A
B
D
#
#
E
#
#
C
F
#
G
#
#
#
ABD\#\#E\#\#CF\#G\#\#\#
ABD##E##CF#G###
读取第4个字符#,说明D的左子树为空。然后递归创建D的右子树。
读取第5个字符#,说明D的右子树为空,如图。然后递归创建B的右子树。
读取第6个字符E,创建一个新节点,作为B的右子树,如图。然后递归创建E的左子树。
读取第7个字符#,说明E的左子树为空。然后递归创建E的右子树。
读取第8个字符#,说明E的右子树为空,如图。然后递归创建A的右子树。
读取第9个字符C,创建一个新节点,作为A的右子树,如图。然后递归创建C的左子树。
先创建一个结构体(内部类),包含数据域,和两个孩子指针域。(不能说跟上面很像,只能说跟上面一模一样)
c++代码如下(示例):
typedef struct BNode{
char data;
BNode *lchild,*rchild;
}*Btree;
java代码如下(示例):
public static class BNode{
String data;
BNode lchild,rchild;
}
创建树
c++代码如下(示例):
void CreateTree(Btree &T){
char ch;
cin>>ch;
if(ch != '#'){
T = new BNode;
T->data = ch;
CreateTree(T->lchild);
CreateTree(T->rchild);
}else{
T = NULL;
}
}
java代码如下(示例):
public BNode createTree(BNode T){
Scanner sc = new Scanner(System.in);
String ch = sc.nextLine();
if(ch.equals("#")){
T = null;
}else{
T = new BNode();
T.data = ch;
T.lchild = createTree(T.lchild);
T.rchild = createTree(T.rchild);
}
return T;
}
下期预告:二叉树的遍历
明天最后一篇,放假!!!2月7号再更新。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。