当前位置:首页 » 存储配置 » 建树的存储结构

建树的存储结构

发布时间: 2023-09-03 00:49:04

Ⅰ 十一、设计在链式存储结构上建立一棵二叉树的算法

二叉树存储结构采用链式存储结构,对于满二叉树与完全二叉树可以按层序进行顺序4.3关系代数关系数据库系统的特点之一是它建立在数据理论的基础之上,有

Ⅱ 急!二叉树的存储结构,并完成:建立、查找、计算结点数、求高度、三种遍历方式

public class BinaryTree<E> //二叉树类
{
protected BinaryNode<E> root; //根结点

public BinaryTree() //构造空二叉树
{
root=null;
}

public BinaryTree(BinaryNode<E> root) //构造指定根结点的二叉树
{
this.root=root;
}

public boolean isEmpty() //判断是否空二叉树
{
return this.root==null;
}

public BinaryNode<E> getRoot() //返回二叉树的根结点
{
return this.root;
}

//6.3.3 二叉树的遍历
public void preOrder() //先根次序遍历二叉树
{
System.out.print("\n先根序列: ");
preOrder(root);
}

private void preOrder(BinaryNode<E> p) //先根次序遍历以p结点为根的子二叉树
{
if(p!=null) //若二叉树不空
{
System.out.print(p.data+" "); //访问当前结点
preOrder(p.left); //按先根次序遍历当前结点的左子树
preOrder(p.right); //按先根次序遍历当前结点的右子树
}
}

public void inOrder() //中根次序遍历二叉树
{
System.out.print("\n中根序列: ");
inOrder(root);
}

private void inOrder(BinaryNode<E> p) //中根次序遍历以p结点为根的子二叉树
{
if (p!=null)
{
inOrder(p.left); //中根次序遍历左子树
System.out.print(p.data+" ");
inOrder(p.right); //中根次序遍历右子树
}
}

public void postOrder() //后根次序遍历二叉树
{
System.out.print("\n后根序列: ");
postOrder(root);
}

private void postOrder(BinaryNode<E> p) //后根次序遍历以p结点为根的子二叉树
{
if (p!=null)
{
postOrder(p.left);
postOrder(p.right);
System.out.print(p.data+" ");
}
}

//【例6.1】 构造并遍历二叉树。

//3. 基于遍历的操作
public int count() //求一棵二叉树中所有结点个数
{
return count(root);
}
public int count(BinaryNode<E> p) //求以p结点为根的子树的结点个数
{
if (p!=null)
return 1+count(p.left)+count(p.right);
else
return 0;
}

public int depth() //求二叉树的深度
{
return depth(root);
}
public int depth(BinaryNode<E> p) //求以p结点为根的子树的深度,后根次序遍历
{
if (p!=null)
{
int ld = depth(p.left); //求左子树的深度
int rd = depth(p.right);
return (ld>=rd) ? ld+1 : rd+1;
}
return 0;
}

public BinaryNode<E> search(E value) //查找值为value的结点
{
return search(root, value);
}
public BinaryNode<E> search(BinaryNode<E> p, E value) //在以p为根的子树中查找值为value的结点
{ //先根次序遍历,返回查找到结点,若未找到返回null
BinaryNode<E> find=null; //记载找到结点
if (p!=null && value!=null)
{
if (p.data.equals(value))
find = p; //查找成功
else
{
find = search(p.left, value); //在左子树中查找
if (find==null)
find=search(p.right, value); //若左子树中未找到,则继续在右子树中查找
}
}
return find; //返回找到结点
}

public BinaryNode<E> getParent(BinaryNode<E> node) //返回指定结点node的父母结点
{ //若空树、未找到或node为根,返回null
if (root==null || node==null || node==root)
return null;
return getParent(root, node);
}
public BinaryNode<E> getParent(BinaryNode<E> p, BinaryNode<E> node)
{ //在以p为根的子树中查找并返回node结点的父母结点
BinaryNode<E> find=null; //记载找到结点
if (p!=null)
{
if (p.left==node || p.right==node)
find = p; //查找成功
else
{
find = getParent(p.left, node); //在左子树中查找
if (find==null)
find = getParent(p.right, node); //若左子树中未找到,则继续在右子树中查找
}
}
return find; //返回找到的父母结点
}

//6.3.4 构造二叉树
// 1、以先根、中根次序遍历序列建立二叉树
public BinaryTree(String prestr,String instr) //1、以先根、中根次序遍历序列建立二叉树
{
root=create(prestr,instr);
//root=create2(prestr,instr);
}

public BinaryNode create(String prestr, String instr)
{
BinaryNode<String> p=null;
int k,n;
String first,presub,insub;
n=prestr.length();
if(n>0)
{
System.out.print("prestr="+prestr+"\t instr="+instr);
first=prestr.substring(0,1);
p=new BinaryNode<String>(first);
k=instr.indexOf(first);
System.out.println("\t first="+first+"\t k="+k);
presub=prestr.substring(1,k+1);
insub=instr.substring(0,k);
p.left=create(presub,insub);
presub=prestr.substring(k+1,n);
insub=instr.substring(k+1,n);
p.right=create(presub,insub);
}
return p;
}
public BinaryNode create2(String instr, String poststr) //以中根、后根次序遍历序列建立二叉树
{
BinaryNode<String> p=null;
int k,n;
String last,postsub,insub;
n=poststr.length();
if(n>0)
{
System.out.print("instr="+instr+"\t poststr="+poststr);
last=poststr.substring(poststr.length()-1,poststr.length());
p=new BinaryNode<String>(last);
k=instr.indexOf(last);
System.out.println("\t last="+last+"\t k="+k);
postsub=poststr.substring(0,k);
insub=instr.substring(0,k);
p.left=create2(insub,postsub);
postsub=poststr.substring(k,n-1);
insub=instr.substring(k+1,n);
p.right=create2(insub,postsub);
}
return p;
}

// 2、以标明空子树的先根序列构造一棵二叉树
public BinaryTree(E[] preorder) //2、以标明空子树的先根序列构造一棵二叉树
{
root=create(preorder);
}

private int i=0;
private BinaryNode<E> create(E[] preorder) //创建一棵子树,当前结点值是preorder[i]
{ //返回所创建子树的根结点
BinaryNode<E> p = null;
if (i<preorder.length)
{
E elem=preorder[i];
i++;
if (elem!=null)
{
p = new BinaryNode<E>(elem); //建立p结点
p.left = create(preorder); //建立p的左子树
p.right = create(preorder); //建立p的右子树
}
}
return p;
}
// 3、以广义表表示建立二叉树
public BinaryTree(String GenListStr)
{
System.out.println("GenListStr="+GenListStr);
if(GenListStr.length()>0)
root=create(GenListStr); //以GenListStr的全部元素建立一棵二叉树
}
public BinaryNode create(String GenListStr) //以GenListStr的部分元素(从i开始)建立一棵子树
{
BinaryNode p=null;
char ch=GenListStr.charAt(i);
if(ch>='A' && ch<='Z') //大写字母
{
p=new BinaryNode<String>(ch+""); //建立结点
i++; //跳过大写字母
ch=GenListStr.charAt(i);
if(ch=='(')
{
i++; //跳过(
p.left=create(GenListStr); //建立左子树
i++; //跳过#
p.right=create(GenListStr); //建立右子树
i++; //跳过)
}
}
if(ch=='#')
i++; //跳过#
return p; //ch非大写字母时,返回null
}

//【例6.2】 输出二叉树中指定结点的所有祖先结点。

//6.3.5 二叉树的插入和删除操作
public void insert(BinaryNode<E> p, E element, boolean leftChild) //插入元素element作为p结点的孩子
{ //若leftChild为true,插入结点作为左孩子,否则作为右孩子
if (p!=null)
{
BinaryNode<E> q = new BinaryNode<E>(element);
if (leftChild)
{
q.left = p.left; //p结点的原左孩子成为q结点的左孩子
p.left = q; //q结点作为p结点的左孩子
}
else
{
q.right = p.right; //p结点的原右孩子成为q结点的右孩子
p.right = q; //q结点作为p结点的右孩子
}
}
}
public void insert(BinaryNode<E> p, E element) //插入元素element作为p结点的左孩子
{
insert(p, element, true);
}

public void remove(BinaryNode<E> p, boolean leftChild) //删除p结点的左/右子树
{ //若leftChild为true,删除左子树,否则删除右子树
if (p!=null)
{
if (leftChild)
p.left = null;
else
p.right = null;
}
}
public void remove(BinaryNode<E> p) //删除p结点的左子树
{
remove(p, true);
}

//6.3.6 二叉树遍历的非递归算法
public void preOrderTraverse() //先根次序遍历二叉树的非递归算法
{
System.out.print("先根次序遍历(非递归): ");
LinkedStack<BinaryNode<E>> stack = new LinkedStack<BinaryNode<E>>(); //创建一个空栈
BinaryNode<E> p = this.root;
while(p!=null || !stack.isEmpty()) //p非空或栈非空时
if(p!=null)
{
System.out.print(p.data+" "); //访问结点
stack.push(p); //p结点入栈
p=p.left; //进入左子树
}
else //p为空且栈非空时
{
p=stack.pop(); //p指向出栈结点
p=p.right; //进入右子树
}
System.out.println();
}

public void inOrderTraverse() //中根次序遍历二叉树的非递归算法
{
System.out.print("中根次序遍历(非递归): ");
LinkedStack<BinaryNode<E>> stack = new LinkedStack<BinaryNode<E>>(); //创建一个空栈
BinaryNode<E> p = this.root;
while(p!=null || !stack.isEmpty()) //p非空或栈非空时
if(p!=null)
{
stack.push(p); //p结点入栈
p=p.left; //进入左子树
}
else //p为空且栈非空时
{
p=stack.pop(); //p指向出栈结点
System.out.print(p.data+" "); //访问结点
p=p.right; //进入右子树
}
System.out.println();
}
//后根次序未写

//6.3.7 二叉树的层次遍历
public void levelOrder() //按层次遍历二叉树
{
LinkedQueue<BinaryNode<E>> que=new LinkedQueue<BinaryNode<E>>(); //创建一个空队列
BinaryNode<E> p=this.root;
System.out.print("层次遍历: ");
while(p!=null)
{
System.out.print(p.data+ " ");
if(p.left!=null)
que.enqueue(p.left); //p的左孩子结点入队
if(p.right!=null)
que.enqueue(p.right); //p的右孩子结点入队
p = que.dequeue(); //p指向出队结点
}
System.out.println();
}

//第6章习题
public void leaf() //遍历输出叶子结点
{
leaf(root);
}
private void leaf(BinaryNode<E> p) //先根次序遍历,输出叶子结点,3种遍历次序结果一样
{
if(p!=null)
{
if (p.isLeaf())
System.out.print(p.data+" ");
leaf(p.left);
leaf(p.right);
}
}

public int countLeaf() //求一棵二叉树中所有叶子结点个数
{
return countLeaf(root);
}
private int countLeaf(BinaryNode<E> p) //求以p结点为根的子树的叶子结点个数
{
if (p==null)
return 0;
if (p.isLeaf())
return 1;
return countLeaf(p.left)+countLeaf(p.right);
}

public BinaryTree(BinaryTree<E> bitree) //以已知的bitree构造二叉树
{
this.root = (bitree.root);
}

private BinaryNode<E> (BinaryNode<E> p) //复制以p根的子二叉树
{
BinaryNode<E> q = null;
if(p!=null)
{
q = new BinaryNode<E>(p.data);
q.left = (p.left); //复制左子树
q.right = (p.right); //复制右子树
}
return q; //返回建立子树的根结点
}

public boolean equals(Object obj) //比较两棵二叉树是否相等
{
if (obj == this)
return true;
if (obj instanceof BinaryTree)
{
BinaryTree<E> bitree = (BinaryTree)obj;
return equals(this.root, bitree.root);
}
return false;
}
private boolean equals(BinaryNode<E> p, BinaryNode<E> q) //判断以p和q结点为根的两棵子树是否相等
{ //递归方法
if(p==null && q==null)
return true;
if(p!=null && q!=null)
return (p.data.equals(q.data)) && equals(p.left, q.left) && equals(p.right, q.right);
return false;
}

public boolean replace(E old, E value) //将首次出现的值为old结点值替换为value
{
BinaryNode<E> find=search(old); //查找值为old的结点
if(find!=null)
find.data = value; //替换结点元素值
return find!=null;
}

public void replaceAll(E old, E value) //将值为old的结点全部替换为value
{
replaceAll(root, old, value);
}
private void replaceAll(BinaryNode<E> p, E old, E value) //在以p为根的子树中实现全部替换
{
if(p!=null)
{
if(p.data.equals(old))
p.data = value;
replaceAll(p.left, old, value);
replaceAll(p.right, old, value);
}
}

public static void main(String args[])
{
String[] preorder = {"A","B","D",null,"G",null,null,null,"C","E",null,null,"F","H"};
BinaryTree<String> bitree = new BinaryTree<String>(preorder);
preorder[0]="Z";
bitree.preOrder();
bitree.inOrder();
bitree.postOrder();
System.out.println("\n结点个数: "+bitree.count());
System.out.println("高度: "+bitree.depth());
System.out.print("叶子结点: ");
bitree.leaf();
System.out.println(" , 共"+bitree.countLeaf()+"个");

BinaryTree<String> bitree2 = new BinaryTree<String>(bitree);
System.out.println("两棵二叉树相等? "+bitree.equals(bitree2));
System.out.println("第2棵二叉树替换(\"D\",\"F\"): "+bitree2.replace("D","F"));

System.out.println("两棵二叉树相等? "+bitree.equals(bitree2));
System.out.println("第2棵二叉树全部替换(\"F\",\"Y\") ");
bitree2.replaceAll("F","Y");
bitree2.preOrder();

BinaryNode<String> find = bitree.search("D"); //查找
bitree.insert(find, "Z");
System.out.println("插入Z作为 "+find.data+" 的左孩子\n");
bitree.levelOrder();
bitree.preOrderTraverse();
bitree.inOrderTraverse();

String[] preorder2 = {"A","B",null,null,"C"}; //标明空子树的先根序列
BinaryTree<String> bitree3 = new BinaryTree<String>(preorder2);
bitree3.preOrder();
bitree3.inOrder();
bitree3.postOrder();
/*
BinaryTree<String> bitree4 = new BinaryTree<String>(preorder2);
bitree4.root = bitree4.create(preorder2); //错,i越界,私有化可避免问题
bitree4.preOrder();
*/
String[] preorder3 = {"D","B","A",null,null,"C",null,null,"E"}; //二叉排序树
BinaryTree<String> bitree5 = new BinaryTree<String>(preorder3);
bitree5.inOrder();
System.out.println("\n二叉排序树? "+bitree5.isSorted());

}

//第8章习题
public boolean isSorted() //判断一棵二叉树是否为二叉排序树
{
return isSorted(this.root);
}
public boolean isSorted(BinaryNode<E> p)
{
boolean yes = true;
if (p!=null)
{
if (!(p.data instanceof Comparable))
return false;
Comparable cmpobj = (Comparable)p.data;
if ((p.left==null || p.left!=null && cmpobj.compareTo(p.left.data)>0) &&
(p.right==null || p.right!=null && cmpobj.compareTo(p.right.data)<0))
{
yes = isSorted(p.left);
if (yes)
yes = isSorted(p.right);
}
else
yes = false;
}
return yes;
}

}

/*
程序运行结果如下:
先根序列: A B D G C E F H
中根序列: D G B A E C H F
后根序列: G D B E H F C A
结点个数: 8
高度: 4
叶子结点: G E H , 共3个
两棵二叉树相等? true
第2棵二叉树替换("D","F"): true
两棵二叉树相等? false
第2棵二叉树全部替换("F","Y")

先根序列: A B Y G C E Y H
第1棵二叉树查找: D
层次遍历: A B C D E F Z G H
先根次序遍历(非递归): A B D Z G C E F H
中根次序遍历(非递归): Z D G B A E C H F

先根序列: A B D G C E F H
中根序列: D G B A E C H F
后根序列: G D B E H F C A

中根序列: A B C D E
二叉排序树? true

*/
这是二叉树的所有方法 及实现实例
还有就是需要建立节点类 你应该知道怎么建的吧

Ⅲ 采用顺序存储方法和链式存储方法分别画出图6.1所示二叉树的存储结构。【在线等】

线性是线性,顺序是顺序,线性是逻辑结构,顺序是储存结构,两者不是一个概念。线性是指一个节点只有一个子节点,而树,或二叉树一个节点后有多个子节点,且子节点不能相互联系。

顺序存储可能会浪费空间(在非完全二叉树的时候),但是读取某个指定的节点的时候效率比较高。

链式存储相对二叉树比较大的时候浪费空间较少,但是读取某个指定节点的时候效率偏低。

二叉树的顺序存储,寻找后代节点和祖先节点都非常方便,但对于普通的二叉树,顺序存储浪费大量的存储空间,同样也不利于节点的插入和删除。因此顺序存储一般用于存储完全二叉树。

链式存储相对顺序存储节省存储空间,插入删除节点时只需修改指针,但回寻找指定节点时很不方便。不过普通答的二叉树一般是用链式存储结构。

(3)建树的存储结构扩展阅读:

(1)完全二叉树——若设二叉树的高度为h,除第h层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。

(2)满二叉树——除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。

(3)平衡二叉树——平衡二叉树又被称为AVL树(区别于AVL算法),它是一棵二叉排序树,且具有以下性质:是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

二叉树是树的一种特殊情形,是一种更简单而且应用更加广泛的树。

Ⅳ 用c语言编写:建立一棵以二叉链表结构存储的二叉树,并对其进行遍历。求该二叉树中的结点个数等操作。

存储结构
typedef struct {
int weight;
int parent, lchild, rchild;
} HTNode ,*HuffmanTree; // 动态分配数组存储huffman树
算法设计
void createHuffmantree(){
ht=(HuffmanTree)malloc(m+1)*sizeof(HTNode);// 动态分配数组存储huffman树,0号单元未用
// m:huffman 树中的结点数(m=2*n-1)
for (i=1;i<=m;++i)
ht[i].parent= ht[i]->lch= ht[i]->rch=0;
for (i=1;i<=n;++i)
ht[i].weight=w[i]; //初始化,w[i]:n个叶子的权值
for (i=n+1;i<=m,++i) { //建哈夫曼树
select(i-1),s1,s2); //在ht[k](1<=k<=i-1)中选择两个双亲域为零而权值取最小的结点 :s1和s2
ht[s1].parent= ht[s2].parent=i;
ht[i].lch=s1;
ht[i].rch=s2;
ht[i].weight=ht[s1].weight + ht[s2].weight ;
};
}

Ⅳ 树的存储表示是什么

树的存储结构根据应用的不同而不同,有的从双亲的角度考虑,引出了双亲表示法,有的从孩子的角度考虑,给出孩子表示法,还有的从孩子和兄弟的角度来讨论。这些都是人们在大量的应用中所使用的不同形式的存储结构,这里介绍常用的双亲表示法、孩子表示法、双亲孩子表示法和孩子兄弟表示法。

1.双亲表示法由树的定义可知,树中每个结点都有且仅有一个双亲结点,根据这一特性,可以用一组连续的一维数组来存储树中的各个结点(一般按层次存储),数组中的一个元素对应树中的一个结点,其中包括结点的数据信息以及该结点的双亲在数组中的下标。树的这种存储方法称为双亲表示法,双亲表示法的结点结构如图1所示,其中,data表示数据域,存储树中结点的数据信息,parent表示指针域,存储该结点的双亲在数组中的下标。

1.双亲表示法的存储结构2)双亲表示法示例图1所示的树的双亲表示如图1所示,这是一棵树及其双亲表示法的存储结构。根结点A无双亲,所以parent的值为-1,G、H和I的parent值为4,表示它们的双亲是下标为4的结点E。这种存储结构利用任一结点的双亲是唯一的性质,可以方便地直接找到任一结点的双亲结点,但求结点的孩子结点时需要扫描整个数组。

图1树的双亲表示法示例

Ⅵ 数据结构 c语言版二叉树(1) 建立一棵含有n个结点的二叉树,采用二叉链表存储;

#include<stdio.h>
#include<stdlib.h>
typedef struct node *tree_pointer;
struct node{
char ch;
tree_pointer left_child,right_child;
};
tree_pointer root=NULL;
tree_pointer create(tree_pointer ptr)
{
char ch;
scanf("%c",&ch);
if(ch==' ')
ptr=NULL;
else{
ptr=(tree_pointer)malloc(sizeof(node));
ptr->ch=ch;
ptr->left_child=create(ptr->left_child);
ptr->right_child=create(ptr->right_child);
}
return ptr;
}
void preorder(tree_pointer ptr)
{
if(ptr){
printf("%c",ptr->ch);
preorder(ptr->left_child);
preorder(ptr->right_child);
}
}
void inorder(tree_pointer ptr)
{
if(ptr){
inorder(ptr->left_child);
printf("%c",ptr->ch);
inorder(ptr->right_child);
}
}
void postorder(tree_pointer ptr)
{
if(ptr){
postorder(ptr->left_child);
postorder(ptr->right_child);
printf("%c",ptr->ch);
}
}
void main()
{
printf("构建一个二叉树(结点数为n):\n");
root=create(root);
printf("前序遍历二叉树:\n");
preorder(root);
printf("\n");
printf("中序遍历二叉树:\n");
inorder(root);
printf("\n");
printf("后序遍历二叉树:\n");
postorder(root);
printf("\n");
}

Ⅶ 数据结构,树的常用存储方式

存入文本文件,每行:孩子节点-父节点。
这样也方便用Hadoop进行处理。

热点内容
ftpdos命令上传 发布:2025-01-31 08:14:44 浏览:105
intenumjava 发布:2025-01-31 08:14:37 浏览:802
android3x 发布:2025-01-31 08:13:03 浏览:600
如何购买安卓版live2d 发布:2025-01-31 08:13:01 浏览:279
python交互输入 发布:2025-01-31 08:12:53 浏览:427
requestdatapython 发布:2025-01-31 08:02:01 浏览:44
javades加密工具 发布:2025-01-31 07:54:04 浏览:244
电话如何配置ip 发布:2025-01-31 07:48:48 浏览:300
2021奔驰e300l哪个配置性价比高 发布:2025-01-31 07:47:14 浏览:656
sqlserver2008光盘 发布:2025-01-31 07:32:13 浏览:578