- 利用广义表A(B(D,E),C(F,G))创建二叉树,利用栈来辅助,这里使用数组模拟栈。原则如下:
(1)遇到节点数据如'A','B','C'等数据,则创建新节点,并分配内存空间;
(2)遇到左括号'(',表明左子树开始(flag=0),根节点入栈;
(3)遇到逗号',',表明右子树开始(flag=1);
(4)遇到右括号,表明子树创建结束,根节点出栈。
2. 图示:待补充
3.示例代码:
void CreateBTreeUseList( BTree<char>*& node)
{
char ch; //节点数据
BTree<char>* st[100]{nullptr}; //用数组模拟栈
BTree<char>* p = nullptr; //节点
char flag = 2; //左右子树的标识
int8_t top = -1; //栈顶指针
while ((ch = getchar()) != '\n') //遇到换行符二叉树创建结束
{
switch (ch)
{
case '(': //遇到左括号,根节点入栈,
st[++top] = p;
flag = 0; //左子树开始
break;
case ',':
flag = 1; //右子树开始
break;
case ')': //遇到右括号,根节点出栈
top--;
break;
default: //遇到节点数据,分配内存,创建新节点
p = new BTree<char>();
p->leftSubTree = nullptr;
p->rightSubTree = nullptr;
p->data = ch;
if (nullptr == mRoot) //保存整个树的根节点
mRoot = p;
else
{
switch (flag) //节点的左右子树
{
case 0: //左子树
st[top]->leftSubTree = p;
break;
case 1: //右子树
st[top]->rightSubTree = p;
break;
default:
break;
}
}
break;
}
}
}
4.运行结果:
int main()
{
BinaryTree<char> bt;
cout << "后序遍历:";
bt.postOrderVisit();
cout << endl << "打印二叉树:";
bt.PrintBTree();
return 0;
}
codeblock下运行结果:
A(B(C,D(,F(E,G))),H(I(J(,L(,M)),K)))
后序遍历:C E G F D B M L J K I H A
打印二叉树:A(B(C,D(,F(E,G))),H(I(J(,L(,M)),K))
5.附录:完整的二叉树C++文件:
#ifndef BINARYTREE_H_INCLUDED
#define BINARYTREE_H_INCLUDED
#include <iostream>
using namespace std;
template <typename T>
struct BTree
{
T data;
struct BTree* leftSubTree;
struct BTree* rightSubTree;
};
template <class T>
class BinaryTree
{
};
template <>
class BinaryTree<char>
{
public:
BinaryTree()
{
mRoot = nullptr;
//CreateBTree(mRoot); //AB#E##C#G##
CreateBTreeUseList(mRoot);
}
virtual ~BinaryTree()
{
DestroyBTree(mRoot);
}
void postOrderVisit()
{
PostOrderVisit(mRoot);
}
size_t high()
{
return High(mRoot);
}
size_t width()
{
return Width();
}
//查找
bool findBTree(char ch)
{
return FindBTree(mRoot,ch);
}
//输出
void PrintBTree()
{
printBTree(mRoot);
}
private:
//以广义表的形式输出树
void printBTree(BTree<char>* node)
{
if (nullptr != node)
{
cout << node->data;
if (node->leftSubTree != nullptr )
{
cout << "(";
printBTree(node->leftSubTree);
}
if (node->rightSubTree != nullptr)
{
if (node->leftSubTree == nullptr)
cout << "(";
cout << ",";
printBTree(node->rightSubTree);
cout << ")";
}
}
else
return;
}
//查找
bool FindBTree(BTree<char>* node,char ch)
{
if (nullptr == node)return false;
else
{
if (ch == node->data)
return true;
else
{
if (FindBTree(node->leftSubTree,ch))
return true;
if (FindBTree(node->rightSubTree,ch))
return true;
return false;
}
}
}
//销毁二叉树
void DestroyBTree(BTree<char>* node)
{
if (nullptr == node)
{
return;
}else
{
DestroyBTree(node->leftSubTree);
DestroyBTree(node->rightSubTree);
delete node;
}
}
//创建二叉树
void CreateBTree( BTree<char>*& node)
{
char ch = getchar();
if ('\n' == ch)
return;
else if (ch == '#')
{
node = nullptr;
}else
{
node = new BTree<char>();
node->data = ch;
/*
if (nullptr == mRoot)
{
mRoot = node;
}
*/
CreateBTree(node->leftSubTree);
CreateBTree(node->rightSubTree);
}
}
//利用广义表创建二叉树
void CreateBTreeUseList( BTree<char>*& node)
{
char ch;
BTree<char>* st[100]{nullptr};
BTree<char>* p = nullptr;
char flag = 2;
int8_t top = -1;
while ((ch = getchar()) != '\n')
{
switch (ch)
{
case '(':
st[++top] = p;
flag = 0; //左子树开始
break;
case ',':
flag = 1; //右子树开始
break;
case ')':
top--;
break;
default:
p = new BTree<char>();
p->leftSubTree = nullptr;
p->rightSubTree = nullptr;
p->data = ch;
if (nullptr == mRoot)
mRoot = p;
else
{
switch (flag)
{
case 0: //左子树
st[top]->leftSubTree = p;
break;
case 1: //右子树
st[top]->rightSubTree = p;
break;
default:
break;
}
}
break;
}
}
}
//后序遍历
void PostOrderVisit(BTree<char>*& node)
{
if (nullptr == node)
return;
else
{
PostOrderVisit(node->leftSubTree);
PostOrderVisit(node->rightSubTree);
cout << node->data << " ";
}
}
//求树的高度
size_t High(BTree<char>*& node)
{
if (nullptr == node)
return 0;
else
return Max(High(node->leftSubTree),High(node->rightSubTree)) + 1;
}
size_t Max(size_t a,size_t b)
{
return a>b ? a: b;
}
//求树的宽度
#define MAX_SIZE (50)
size_t Width()
{
if (nullptr == mRoot)
return 0;
BTree<char>* q[MAX_SIZE]={nullptr};
size_t last = 0,fr=0,rear=1;
size_t tmp=0;
size_t maxw=0;
q[rear] = mRoot;
BTree<char>* p = nullptr;
while (fr <= last)
{
fr++;
fr = fr % MAX_SIZE;
p = q[fr];
if (nullptr != p)
tmp++;
if (nullptr != p && p->leftSubTree != nullptr)
{
rear++;
rear = rear % MAX_SIZE;
q[rear] = p->leftSubTree;
}
if (nullptr != p && p->rightSubTree != nullptr)
{
rear++;
rear = rear % MAX_SIZE;
q[rear] = p->rightSubTree;
}
if (fr >= last)
{
last = rear;
if (tmp > maxw)
maxw = tmp;
tmp = 0;
}/*
if (nullptr == p)
break;
*/
}
return maxw;
}
private :
BTree<char>* mRoot;
};
#endif // BINARYTREE_H_INCLUDED