降维问题:顺序、链式存储结构的二叉树递归遍历、层次遍历求高度
全部源代码在最后
一、概要设计
测试数据:如图所示森林
森林采用兄弟孩子链表表示法。
森林的数据输入采取输入兄弟孩子链表表示法下的等价二叉树的扩展先序遍历形成的线性串的方法(原理为森林先序遍历结果与等价二叉树的先序遍历结果相同)
输入数据:ABEK..F..CG..DH.I.J...L.MN...
算法设计
以链式存储结构为例
递归遍历求高度:由于孩子兄弟链表表示法是把兄弟当儿子,所以对应二叉树的所有左子树的最大高度便是森林的高度。这样,在求二叉树高度的算法上可以改进,将左子树给定权重1,右子树给定权重0;即只需
if(root == NULL) return 0;
return max(GetHeightByRecursion(root->firstson) + 1, GetHeightByRecursion(root->nextbrother));
层次遍历求高度:利用队列,将第一个儿子入队,再进行一系列循环操作
实验结果
二、 详细设计
1. 链式存储结构
- 森林链表
template<typename T>
struct ForestNode
{
T data;
ForestNode<T>* firstson;
ForestNode<T>* nextbrother;
ForestNode()
{
firstson = NULL;
nextbrother = NULL;
}
};
- 森林类
template<typename T>
class Forest
{
public:
Forest() {};
~Forest(){};
ForestNode<T>* getFirstTreeRoot(){};
void build(ForestNode<T>* & node){};
void deleteAll(ForestNode<T>* node){};
int LevelTraversalAndReturnHeight(ForestNode<T>* root){};
int GetHeightByRecursion(ForestNode<T>* root){};
private:
ForestNode<T>* FirstTreeRoot;
};
- 构造函数
Forest()
{
FirstTreeRoot = new ForestNode<T>;
};
- 析构函数
~Forest()
{
deleteAll(FirstTreeRoot);
}
- 获得第一个根结点
ForestNode<T>* getFirstTreeRoot() { return FirstTreeRoot; };
- 通过输入先序拓展遍历序列递归建立森林
void build(ForestNode<T>* & node)
{
T nodedata;
nodedata = cin.get();
if (nodedata == '.')
{
node = NULL;
return;
}
node = new ForestNode<T>;
node->data = nodedata;
build(node->firstson);
build(node->nextbrother);
}
- 删除子树
void deleteAll(ForestNode<T>* node)
{
if (node == NULL) return;
deleteAll(node->firstson);
deleteAll(node->nextbrother);
delete node;
}
- 层次遍历并返回高度
int LevelTraversalAndReturnHeight(ForestNode<T>* root)
{
queue<ForestNode<T>*> Queue;
Queue.push(root);
int height = 0;
while (Queue.size() != 0)
{
cout << "level" << height + 1 << ":";
int len = Queue.size();
ForestNode<T>* node;
for (int i = 1; i <= len; i++)
{
node = Queue.front();
Queue.pop();
while (node != NULL)
{
cout << node->data << " ";
if (node->firstson != NULL) Queue.push(node->firstson);
node = node->nextbrother;
}
cout << " ";
}
cout << endl;
height++;
}
return height;
}
- 递归遍历求高度()
int GetHeightByRecursion(ForestNode<T>* root)
{
if(root == NULL) return 0;
return max(GetHeightByRecursion(root->firstson) + 1, GetHeightByRecursion(root->nextbrother));
}
2.顺序存储结构
template<typename T>
class SeqForest
{
public:
SeqForest(int totalnum)
{
if (totalnum > 0)
{
this->totalnum = totalnum;
array = new T[totalnum + 1];
memset(array, ' ', (totalnum + 1) * sizeof(T));
}
}
~SeqForest()
{
delete[]array;
}
void build(int index = 1)
{
T data;
data = cin.get();
if (data == '.'||index>totalnum) return;
array[index] = data;
build(2 * index);
build(2 * index + 1);
}
int GetHeightByRecursion(int i = 1)
{
if (i> totalnum || array[i] == ' ') return 0;
return max(GetHeightByRecursion(2 * i) + 1, GetHeightByRecursion(2 * i + 1));
}
int LevelTraversalAndReturnHeight(int i = 1)
{
queue<int> Queue;
Queue.push(i);
int height = 0;
while (!Queue.empty())
{
cout << "level" << ++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);
cout << array[index] << " ";
index = 2 * index + 1;
}
}
cout << endl;
}
return height;
}
private:
int totalnum;
T* array;
};
三、全部源代码
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
//顺序存储结构
template<typename T>
class SeqForest
{
public:
SeqForest(int totalnum)
{
if (totalnum > 0)
{
this->totalnum = totalnum;
array = new T[totalnum + 1];
memset(array, ' ', (totalnum + 1) * sizeof(T));
}
}
~SeqForest()
{
delete[]array;
}
void build(int index = 1)
{
T data;
data = cin.get();
if (data == '.'||index>totalnum) return;
array[index] = data;
build(2 * index);
build(2 * index + 1);
}
int GetHeightByRecursion(int i = 1)
{
if (i> totalnum || array[i] == ' ') return 0;
return max(GetHeightByRecursion(2 * i) + 1, GetHeightByRecursion(2 * i + 1));
}
int LevelTraversalAndReturnHeight(int i = 1)
{
queue<int> Queue;
Queue.push(i);
int height = 0;
while (!Queue.empty())
{
cout << "level" << ++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);
cout << array[index] << " ";
index = 2 * index + 1;
}
}
cout << endl;
}
return height;
}
private:
int totalnum;
T* array;
};
//链式存储结构
template<typename T>
struct ForestNode
{
T data;
ForestNode<T>* firstson;
ForestNode<T>* nextbrother;
ForestNode()
{
firstson = NULL;
nextbrother = NULL;
}
};
template<typename T>
class Forest
{
public:
Forest()
{
FirstTreeRoot = new ForestNode<T>;
};
~Forest()
{
deleteAll(FirstTreeRoot);
}
ForestNode<T>* getFirstTreeRoot() { return FirstTreeRoot; };
void build(ForestNode<T>* & node)
{
T nodedata;
nodedata = cin.get();
if (nodedata == '.')
{
node = NULL;
return;
}
node = new ForestNode<T>;
node->data = nodedata;
build(node->firstson);
build(node->nextbrother);
}
void deleteAll(ForestNode<T>* node)
{
if (node == NULL) return;
deleteAll(node->firstson);
deleteAll(node->nextbrother);
delete node;
}
int LevelTraversalAndReturnHeight(ForestNode<T>* root)
{
queue<ForestNode<T>*> Queue;
Queue.push(root);
int height = 0;
while (Queue.size() != 0)
{
cout << "level" << height + 1 << ":";
int len = Queue.size();
ForestNode<T>* node;
for (int i = 1; i <= len; i++)
{
node = Queue.front();
Queue.pop();
while (node != NULL)
{
cout << node->data << " ";
if (node->firstson != NULL) Queue.push(node->firstson);
node = node->nextbrother;
}
cout << " ";
}
cout << endl;
height++;
}
return height;
}
int GetHeightByRecursion(ForestNode<T>* root)
{
if(root == NULL) return 0;
return max(GetHeightByRecursion(root->firstson) + 1, GetHeightByRecursion(root->nextbrother));
}
private:
ForestNode<T>* FirstTreeRoot;
};
int main()
{
cout << "Seqeuence storage structure:" << endl;
SeqForest<char> sequenceBT(200);
cout << "Please enter the expanded forest preorder list of Child brother list notation:";
sequenceBT.build();
cout << "Get height by recursion traversal:" << endl;
cout << sequenceBT.GetHeightByRecursion() << endl;
cout << "Forest's level traversal and get height:" << endl;
cout << sequenceBT.LevelTraversalAndReturnHeight() << endl;
cout << endl;
cout << "List storage structure:" << endl;
Forest<char> forest;
ForestNode<char>* root = forest.getFirstTreeRoot();
cin.get();
cout << "Please enter the expanded forest preorder list of Child brother list notation:";
forest.build(root);
cout << "Get height by recursion traversal:";
cout << forest.GetHeightByRecursion(root) << endl;
cout << "Forest's level traversal and get height:" << endl;
cout << forest.LevelTraversalAndReturnHeight(root) << endl;
}