数据结构 实验二 二叉树的操作与实现
利用二叉树的二叉链式存储结构设计并实现各种操作算法。
1、二叉树的基本操作算法实现
(1) 利用二叉树字符串“A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))”创建二叉树的二叉链式存储结构;
(2) 输出该二叉树;
(3) 输出‘H’节点的左、右孩子结点值;
(4) 输出该二叉树的结点个数、叶子结点个数、二叉树的度和高度。
2、二叉树的各种遍历算法实现
实现上述二叉树的先序、中序和后序遍历的递归和非递归算法。
3、线索二叉树的遍历
中序线索化上述二叉树并找出根结点的前驱和后继。
#include<iostream>
#include<iomanip>
#include<stack>
#include<queue>
using namespace std;
struct Node {
char vlaue;
int ltag, rtag;
Node* lchild, * rchild;
Node() {
vlaue = '#'; lchild = NULL; rchild = NULL;
ltag = rtag = 0;
}
};
struct Tree {
Node* Head;
Tree() {
Head = new Node();
}
void initTree(string s) {
Node* tmpNode, * &root=Head->lchild;
stack<Node*>st;
int l = 0, flag = 0, len = s.size();
while (l < len ) {
if (s[l] == '(') {
flag = 1;
st.push(tmpNode);
}
else if (s[l] == ',') {
flag = 2;
}
else if (s[l] == ')') {
st.pop();
}
else {
tmpNode = new Node();
tmpNode->vlaue = s[l];
if (root == NULL)root = tmpNode;
else {
Node*tmproot = st.top();
if (flag == 1)
tmproot->lchild = tmpNode;
else if (flag == 2)
tmproot->rchild = tmpNode;
}
}
l++;
}
}
}*tree;
//输出创建二叉树的字符串
void showTree(Node* root) {
if (root != NULL) {
cout << root->vlaue;
if (root->lchild == NULL && root->rchild == NULL)return;
cout << "(";
showTree(root->lchild);
if (root->rchild != NULL)cout << ",";
showTree(root->rchild);
cout << ")";
}
}
//递归的先序遍历
void Preorder(Node *root) {
if (root != NULL) {
cout << root->vlaue << " ";
Preorder(root->lchild);
Preorder(root->rchild);
}
}
//递归的中序遍历
void Inorder(Node* root) {
if (root != NULL) {
Inorder(root->lchild);
cout << root->vlaue << " ";
Inorder(root->rchild);
}
}
//递归的后序遍历
void Postorder(Node* root) {
if (root != NULL) {
Postorder(root->lchild);
Postorder(root->rchild);
cout << root->vlaue << " ";
}
}
//非递归的先序遍历
void NoRecursivePreorder(Node* root) {
if (root != NULL) {
stack<Node*>st;
while (root != NULL || !st.empty()) {
if (root != NULL) {
cout << root->vlaue << " ";
st.push(root);
root = root->lchild;
}
else {
root = st.top();
st.pop();
root = root->rchild;
}
}
}
}
//非递归的中序遍历
void NoRecursiveInorder(Node* root) {
if (root != NULL) {
stack<Node*>st;
while (root != NULL || !st.empty()) {
if (root != NULL) {
st.push(root);
root = root->lchild;
}
else {
root = st.top();
st.pop();
cout << root->vlaue << " ";
root = root->rchild;
}
}
}
}
//非递归的后序遍历
void NoRecursivePostorder(Node* root) {
if (root != NULL) {
stack<Node*>st;
Node* tempNode = root, *lastNode = NULL;
//存左子树直到根
while (tempNode != NULL) {
st.push(tempNode);
tempNode = tempNode->lchild;
}
while (!st.empty()) {
tempNode = st.top();
st.pop();
//无右子树
if (tempNode->rchild == NULL || lastNode == tempNode->rchild) {
cout << tempNode->vlaue << " ";
lastNode = tempNode;
}
else {
//存右子树直到根
st.push(tempNode);
tempNode = tempNode->rchild;
while (tempNode) {
st.push(tempNode);
tempNode = tempNode->lchild;
}
}
}
}
}
// 非递归的层次遍历
void layerorder(Node* root) {
queue<Node*>que;
que.push(root);
while (!que.empty()) {
Node *tempNode = que.front();
que.pop();
cout << tempNode->vlaue << " ";
if (tempNode->lchild != NULL)que.push(tempNode->lchild);
if (tempNode->rchild != NULL)que.push(tempNode->rchild);
}
}
//中序线索化上述二叉树并找出根结点的前驱和后继。
Node* pre = NULL;
void ThreadBinaryTree(Node* root) {
if (root!=NULL) {
//处理节点的前驱
ThreadBinaryTree(root->lchild); //找到最左的节点
if (root->lchild == NULL) {
root->lchild = pre;
root->ltag = 1;
}
//处理节点的后继
if (pre != NULL && pre->rchild == NULL) {
pre->rchild = root;
pre->rtag = 1;
}
pre = root;
ThreadBinaryTree(root->rchild);
}
}
//输出‘H’节点的左、右孩子结点值
void FindNode(Node* root, char ch,Node *&tempNode) {
if (tempNode != NULL)return;
else if (root->vlaue == ch)tempNode = root;
else {
if (root->lchild != NULL)FindNode(root->lchild, ch, tempNode);
if (root->rchild != NULL)FindNode(root->rchild, ch, tempNode);
}
}
void Findlrchild(Node* root,char ch) {
Node* tempNode=NULL;
FindNode(root, ch, tempNode);
cout << tempNode->lchild->vlaue << " " << tempNode->rchild->vlaue;
}
//输出该二叉树的结点个数
int NodeNum(Node* root) {
if (root->lchild == NULL && root->rchild == NULL)return 1;
int tmp = 1;
if (root->lchild != NULL)tmp += NodeNum(root->lchild);
if (root->rchild != NULL)tmp += NodeNum(root->rchild);
return tmp;
}
//叶子结点个数
int EndNodeNum(Node*root) {
if (root->lchild == NULL && root->rchild == NULL)return 1;
int tmp = 0;
if (root->lchild != NULL)tmp += EndNodeNum(root->lchild);
if (root->rchild != NULL)tmp += EndNodeNum(root->rchild);
return tmp;
}
//二叉树的高度。
int TreeHeight(Node* root) {
if (root == NULL)return 0;
return TreeHeight(root->lchild) > TreeHeight(root->rchild) ? TreeHeight(root->lchild) + 1 : TreeHeight(root->rchild) + 1;
}
//二叉树的度
int GetBitTHight(Node* root) {
if (root == NULL)return 0;
int tmp = 0;
if ((root->lchild == NULL && root->rchild != NULL))tmp = max(1, GetBitTHight(root->rchild));
if ((root->lchild != NULL && root->rchild == NULL))tmp = max(1, GetBitTHight(root->lchild));
if (root->lchild != NULL && root->rchild != NULL)return 2;
return tmp;
}
int main() {
tree = new Tree();
// A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))
string s; cin >> s;
tree->initTree(s);
cout << "输出创建二叉树的字符串" << endl;
showTree(tree->Head->lchild);
cout << endl;
cout << "输出该二叉树的结点个数:" << NodeNum(tree->Head->lchild) << endl;
cout << "叶子结点个数:" << EndNodeNum(tree->Head->lchild) << endl;
cout << "二叉树的高度:" << TreeHeight(tree->Head->lchild) << endl;
cout << "二叉树的度:" << GetBitTHight(tree->Head->lchild) << endl;
cout << "输出‘H’节点的左、右孩子结点值;";
Findlrchild(tree->Head->lchild, 'H');
cout << endl;
cout << "递归前序遍历:";
Preorder(tree->Head->lchild);
cout << endl;
cout << "递归中序遍历:";
Inorder(tree->Head->lchild);
cout << endl;
cout << "递归后序遍历:";
Postorder(tree->Head->lchild);
cout << endl;
cout << "非递归前序遍历:";
NoRecursivePreorder(tree->Head->lchild);
cout << endl;
cout << "非递归中序遍历:";
NoRecursiveInorder(tree->Head->lchild);
cout << endl;
cout << "非递归后序遍历:";
NoRecursivePostorder(tree->Head->lchild);
cout << endl;
cout << "中序线索化二叉树";
ThreadBinaryTree(tree->Head->lchild);
cout << tree->Head->lchild->lchild->vlaue << " " << tree->Head->lchild->rchild->vlaue << endl;
return 0;
}