森林顺序结构(递归,层次)遍历求高度

森林顺序结构(递归,层次)遍历求高度

对于顺序结构我们利用类的封装要比结点更好更方便一点,因为再顺序结构中,我们需要用到数组,如果每一个结点一个数组就有点麻烦

1. forest类中私有成员函数
我们设置一个 数组array,和他的长度

    private:
	int Max;
	char* array;

2.forest的构造函数

	forest(int Max)
	{
		if (Max > 0)
		{
			this->Max = Max;
			array = new char[Max + 1];
			memset(array,' ',(Max + 1));    //cstring中 
		}
	}
	

memset 函数是将数组全部初始化为空(‘ ’) ,这个函数再cstring中

3.析构函数

~forest()
	{
		delete[]array;
	}

4.构造森林

void build(int index = 1)
	{
		char data;
		data = cin.get();             // cin.get(data);
		if (data == '#'||index>Max) return;
		array[index] = data;
		build(2 * index);
		build(2 * index + 1);
	}

这个函数与之前的构造函数完全不同 ! ! !
我们建立森林的关键是要弄清楚每个点都是谁的儿子,谁的爹,谁的大胸弟
在这个函数中我们要构造这样的关系

如果我们输入了 # ,或者下标大于Max,这个构造函数就结束
如果不是就把他赋值给 array[index]
然后构造他的左孩子 build(2 * index) ,左孩子的下标是他爹的二倍
再构造他的大胸弟,下标是他的 二倍 + 1

5.递归遍历求高度

	int high(int i = 1)
	{
		if (i> Max || array[i] == ' ') return 0;
		return max(high(2 * i) + 1, high(2 * i + 1));  //在头文件 cstdlib 中
	}

如果下标为 i 时他对应的值为空(‘ ’)或者大于Max, 程序结束
之后要返回 左孩子结点+1 和 兄弟结点 的最大值
在森林转为二叉树的逻辑中,新的二叉树中,只要结点有左孩子,就要给他的层次 +1
但右兄弟就不用,不过还是要遍历右兄弟,因为右兄弟的后继结点中可能也有左孩子
这个自己画个图就能好理解一点

6.层次遍历求高度

int dep(int i = 1)
	{
		queue<int> Queue;
		Queue.push(i);
		int height = 0;
		while (!Queue.empty())
		{
			height++;
			int len = Queue.size();
			for (int j = 1; j <= len; j++)
			{
				int index = Queue.front();
				Queue.pop();
				while (array[index] != ' ')
				{
					if (array[2 * index] != ' ') Queue.push(2 * index);
					index = 2 * index + 1;
				}
			}
		}
		return height;
	}

我们要在这里面建立一个队列,用来储存 根结点 和 所有有左孩子的结点
在之后的循环中,我们要看着些在队列中的结点是否还有左孩子
有的话他的左孩子继续入队,再遍历他的右胸弟
只要队列中不空,每经历一次循环森林的层次就 +1

7.主函数

int main()
{
	forest a(200);
	a.build();
	cout<<"森林顺序递归遍历求高度"<<endl; 
    cout<<a.high()<<endl;
    cout<<"森林顺序层次遍历求高度"<<endl; 
    cout<<a.dep();
}

8.输出结果

ABEK##F##CG##DH#I#J###L#MN###

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值