本文章主要包括了以下内容:
创建二叉树类。二叉树的存储结构使用链表。
供操作:前序遍历、中序遍历、后序遍历、层次遍历、计算二叉树结点数目、计算二叉树高度。
接收键盘录入的二叉树前序序列和中序序列(各元素各不相同),输出该二叉树的后序序列。
下面是c++代码:
#include <stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <stack>
using namespace std;
class BinaryTreeNode//二叉树的节点类
{
public:
BinaryTreeNode() { leftChild = rightChild = 0; }
BinaryTreeNode(char c) { data = c; leftChild = rightChild = 0; }
BinaryTreeNode(char c, BinaryTreeNode* left, BinaryTreeNode* right) { data = c; leftChild = left; rightChild = right; }
char data;
BinaryTreeNode* leftChild;
BinaryTreeNode* rightChild;
};
class Node //队列类中用链表存
{
public:
BinaryTreeNode *data;
Node *next;
Node() { next = NULL; }
Node(BinaryTreeNode *item, Node* link = NULL) { data = item; next = link; }
};
//队列类,作为层次遍历的辅助数据结构用
class LinkQueue
{
private:
Node *front, *rear;
public:
LinkQueue() { rear = front = new Node; };
bool empty()
{
return front == rear;
}
void outQueue(BinaryTreeNode * &e)//出队列
{
Node *tmpPtr = front->next;
e = tmpPtr->data;
front->next = tmpPtr->next;
if (rear == tmpPtr) rear = front;
delete tmpPtr;
}
void inQueue(BinaryTreeNode * &e)//入队列
{
Node *tmpPtr = new Node(e);
rear->next = tmpPtr;
rear = tmpPtr;
}
};
//二叉树类
class BinaryTree
{
public:
BinaryTree() { root = 0; }
void getRoot(char* c);
void insertLeftChild(BinaryTreeNode* t, char c)//插入左孩子
{
t->leftChild = new BinaryTreeNode(c);
}
void insertRightChild(BinaryTreeNode* t, char c)//插入右孩子
{
t->rightChild = new BinaryTreeNode(c);
}
void preOrder(BinaryTreeNode *t)//前序遍历
{
if (t)
{
cout << t->data;
preOrder(t->leftChild);
preOrder(t->rightChild);
}
}
void inOrder(BinaryTreeNode* t)//中序遍历
{
if (t)
{
inOrder(t->leftChild);
cout << t->data;
inOrder(t->rightChild);
}
}
void postOrder(BinaryTreeNode* t)//后续遍历
{
if (t)
{
postOrder(t->leftChild);
postOrder(t->rightChild);
cout << t->data;
}
}
void levelOrder(BinaryTreeNode* t)//层次遍历
{
LinkQueue q;
bool isNullAtFirst = true;
while (t)
{
cout << t->data;
if (t->leftChild) q.inQueue(t->leftChild);
if (t->rightChild) q.inQueue(t->rightChild);
if (q.empty()) return;
q.outQueue(t);
}
}
void preOrderForCount(BinaryTreeNode* t)//用了前序遍历的方法来计算二叉树节点数目
{
if (t)
{
count++;
preOrderForCount(t->leftChild);
preOrderForCount(t->rightChild);
}
}
int height(BinaryTreeNode* t)//返回一个节点的高度
{
if (!t) return 0;
int heightLeft = height(t->leftChild);
int heightRight = height(t->rightChild);
if (heightLeft > heightRight) return ++heightLeft;
else return ++heightRight;
}
int size()//返回二叉树节点数目
{
count = 0;
preOrderForCount(root);
return count;
}
BinaryTreeNode* root;
int count = 0;
};
//前序中序生成后序
//前序遍历的第一个元素为根节点,在中序遍历中找到这个根节点,从而可以将中序遍历分为左右两个部分,左边部分为左子树的中序遍历,
//右边部分为右子树的中序遍历,进而也可以将前序遍历除第一个元素以外的剩余部分分为两个部分,第一个部分为左子树的前序遍历,第二
//个部分为右子树的前序遍历。
//上述分析结果,可以递归调用构建函数,根据左子树、右子树的前序、中序遍历的结果输出后序遍历的结果。
void generatePostOrder(char* preOrder, char* inOrder, int length)
{
if (length == 0) return;
BinaryTreeNode* t = new BinaryTreeNode(*preOrder);
int rootIndex = 0;
//前序遍历的第一个元素为根节点,在中序遍历中找到这个根节点
for (; rootIndex < length; rootIndex++)
{
if (inOrder[rootIndex] == *preOrder)
break;
}
//左子树递归
generatePostOrder(preOrder + 1, inOrder, rootIndex);
//右子树递归
generatePostOrder(preOrder + rootIndex + 1, inOrder + rootIndex + 1, length - (rootIndex + 1));
cout << t->data;
return;
}
int main()
{
BinaryTree b;
b.root = new BinaryTreeNode('G');
b.insertLeftChild(b.root, 'D');
b.insertRightChild(b.root, 'M');
b.insertLeftChild(b.root->leftChild, 'A');
b.insertRightChild(b.root->leftChild, 'F');
b.insertLeftChild(b.root->leftChild->rightChild, 'E');
b.insertLeftChild(b.root->rightChild, 'H');
b.insertRightChild(b.root->rightChild, 'Z');
cout << "The preOrder is:";
b.preOrder(b.root);
cout << endl;
cout << "the inOrder is:";
b.inOrder(b.root);
cout << endl;
cout << "the postOrder is:";
b.postOrder(b.root);
cout << endl;
cout << "the levelOrder is:";
b.levelOrder(b.root);
cout << endl;
cout << "这个二叉树的节点数目为:" << b.size() << endl;
cout << "这个二叉树根节点的高度为:" << b.height(b.root) << endl;
cout << endl;
/*
在这里输入前序中序 来输出后序
最好直接输入上面创建好的二叉树的前序中序 来检验后序
当然不嫌麻烦自己画个二叉树 列举出它的前中序来输出后序也可以
*/
char *pre = new char[20];
char *in = new char[20];
cout << "请输入一个二叉树的前序遍历:" << endl;
cin >> pre; //GDAFEMHZ
cout << "请输入一个二叉树的中序遍历:" << endl;
cin >> in; //ADEFGHMZ
cout << "这个二叉树的后序遍历为:" << endl;
generatePostOrder(pre, in, strlen(pre));
system("pause");
return 0;
}