树(3)---树与森林

来源:互联网 发布:rip协议端口号 编辑:程序博客网 时间:2024/05/29 16:50

树的存储结构

树也就是二叉树的加强版,一个头结点有多个后继,其余性质与二叉树相仿。

所以树便有了一种与二叉树相对应的存储方法

孩子兄弟法:

简单的来说,就是一种变种的二叉树,二叉树的结点,一个指针域存储树的孩子(也就是他的子树),一个指针域存储树的兄弟(也就是他相邻的子树),这样便将一棵树使用二叉树的方式储存了。


遍历的改变

先序遍历:

1)访问根结点

2)访问子树

3)访问兄弟树

中序遍历:

1)访问子树

2)访问根结点

3)访问兄弟树

因为不可能先访问兄弟树,也就不存在后序遍历了。


树的创建

这次构造的是一棵无序树,所以选择树的构造方法是一开始创建一棵完整的树。

具体步骤是:

1)输入插入元素

2)测试元素是否为空,为空结束

3)创建新结点,元素插入

4)插入元素孩子结点,重复1~5,(递归调用)

5)插入元素兄弟结点,重复1~5,(递归调用)

这里函数的输入变量,应该为引用。


森林

森林也就是很多树的集合。

一棵树的孩子兄弟表示法是没有右子树的,因为根树是单独的,他没有兄弟。同样的当树不止一棵时,右子树也就能补全了。

代码:

class Node{friend class Tree;int key;//键string data;//数据域Node* child;//孩子域Node* next;//兄弟域Node(int k,string item) :key(k),data(item){}};class Tree{public:void create()//创建树{cout << "输入头结点的键和值:" << endl;create(root);}void LCtrave(){ LCtrave(root); }//先序void CLtrave(){ CLtrave(root); }//中序int leafnum(){ return leafnum(root); }//叶子数int defth(){ return defth(root); }//深度int size()//结点数{int t=size(root);Node* x = root;while (x->next){t += size(x->next);x = x->next;}return t; }private:Node* root = NULL;//根结点//工具函数void create(Node* &x);void visit(Node* x)//打印元素{cout << x->key << ":" << x->data << endl;}void LCtrave(Node* x);void CLtrave(Node* x);int leafnum(Node* x);int defth(Node* x);int size(Node* x);};void Tree::create(Node* &x){string item;int k;cin >> k >> item;if (k==0&&item == "NULL")return;x = new Node(k,item);cout << "请输入" << x->key << "的孩子:" << endl;create(x->child);cout << "请输入" << x->key << "的兄弟:" << endl;create(x->next);}void Tree::LCtrave(Node* x){if (x){visit(x);LCtrave(x->child);LCtrave(x->next);}}void Tree::CLtrave(Node* x){if (x){CLtrave(x->child);visit(x);CLtrave(x->next);}}int Tree::leafnum(Node* x){if (!x)return 0;//结点空返回0if (!x->child)//无孩子必为叶子结点return 1 + leafnum(x->next);else//有孩子,查询孩子和兄弟的结点树return leafnum(x->child) + leafnum(x->next);}int Tree::defth(Node* x){int c, n;if (!x)return 0;else{c = defth(x->child);//孩子深度n = defth(x->next);//兄弟深度return c + 1 > n ? c + 1 : n;//根与兄弟比较谁高返回谁}}int Tree::size(Node* x){if (!x)return 0;int c = 0, n = 0;if (x->child){c = size(x->child);//孩子结点数n = size(x->child->next);//孩子兄弟的结点数}return c + n + 1;}


0 0
原创粉丝点击