对于一棵二叉树,有三种基本遍历方式:
1、前序遍历(DLR):先访问根结点,然后遍历左子树,最后遍历右子树。
归结为:从根结点一直从左子树向下直到叶结点,然后返回到叶结点的父亲,再从其父结点的右子树向下。
2、中序遍历(LDR):先中序遍历左子树,然后访问根结点,最后遍历右子树。
3、后序遍历(LRD):先后序遍历左子树,然后遍历右子树,最后访问根结点。
对如上图,遍历结果如下:
前序遍历的结果是ABDEHCFGI
中序遍历的结果是DBEHAFCIG
后序遍历的结果是DHEBFIGCA
一般情况下,当前结点的左孩子比当前结点值小,当前结点的右孩子比当前结点的值大。
1、插入:
1.1 插入结点的值比当前结点的值小,继续找当前结点的左子树,
1.2 插入结点的值比当前结点的值大,继续找当前结点的右子树,
1.3 找到合适的位置了,插入树。
2、删除:
2.1 删除结点是叶子结点,直接将其删除即可
2.2 删除结点只有左孩子或者只有右孩子,将其孩子结点删除,并将指向孩子结点的分支设置为空,c++是设置为NULL。不过更好的做法是,将孩子结点的值替换到当前结点,再删除孩子结点即可。
2.3 删除的结点同时含有左孩子与右孩子,需要找到删除结点的后继结点,将后继结点作为当前结点。
#include
using namespace std;
typedef int dataType;
//定义二叉树节点
struct tree
{
dataType data;
tree *left;
tree *right;
};
class Btree{
public:
tree *root;
int n;
Btree(){
root = NULL;
}
~Btree(){
}
//创建二叉树并插入数据
void createBtree(dataType data);
//前序遍历
void preOrder(tree *);
//中序遍历
void inOrder(tree *);
//后序遍历
void postOrder(tree *);
//前序显示
void displayPreOrder();
//中序显示
void displayInOrder();
//后序显示
void diaplayPostOrder();
//统计二叉树的个数
int countTree(tree *);
//统计叶子节点的个数
int countLeaf(tree *);
};
void Btree::createBtree(dataType data){
tree *newNode = new tree;
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
if (root == NULL){
root = newNode;
}
else{
tree *backTree = NULL;
tree *currentTree = root;
while (currentTree != NULL){
backTree = currentTree;
if (currentTree->data > data)
currentTree = currentTree->left;
else
currentTree = currentTree->right;
}
if (backTree->data > data)
backTree->left = newNode;
else
backTree->right = newNode;
}
}
//先序遍历(递归方法)
void Btree::preOrder(tree *temp){
if (temp != NULL){
cout << temp->data << " ";
preOrder(temp->left);
preOrder(temp->right);
}
}
//中序遍历(递归方法)
void Btree::inOrder(tree *temp){
if (temp != NULL){
inOrder(temp->left);
cout << temp->data << " ";
inOrder(temp->right);
}
}
//后序遍历(递归方法)
void Btree::postOrder(tree *temp){
if (temp !=NULL){
postOrder(temp->left);
postOrder(temp->right);
cout << temp->data << " ";
}
}
int Btree::countLeaf(tree *temp){
if (temp == NULL)
return 0;
else{
if (temp->left == NULL && temp->right == NULL)
return n += 1;
else{
countLeaf(temp->left);
countLeaf(temp->right);
}
return n;
}
}
//前序遍历显示
void Btree::displayPreOrder(){
preOrder(root);
cout << endl;
}
//中序遍历显示
void Btree::displayInOrder(){
inOrder(root);
cout << endl;
}
//后序遍历显示
void Btree::diaplayPostOrder(){
postOrder(root);
cout << endl;
}
//统计二叉树的个数
int Btree::countTree(tree *temp){
if (temp == NULL)
return 0;
else
return countTree(temp->left) + countTree(temp->right);
}
void main(){
Btree btree = Btree();
int treeArray[] = { 7, 4, 2, 3, 15, 35, 6, 45, 55, 20, 1, 14, 56, 57, 58 };
int k;
k = sizeof(treeArray) / sizeof(treeArray[0]);
cout << "建立排序二叉树顺序: " << endl;
for (int i = 0; i < k; i++){
cout << treeArray[i] << " ";
btree.createBtree(treeArray[i]);
}
cout << endl;
cout << "二叉树的节点个数:" << btree.countTree(btree.root) << endl;
cout << "二叉树的叶子个数:" << btree.countLeaf(btree.root) << endl;
cout << "二叉树先序遍历序列: " << endl;
btree.displayPreOrder();
cout << "二叉树中序遍历序列: " << endl;
btree.displayInOrder();
cout << "二叉树后序遍历序列: " << endl;
btree.diaplayPostOrder();
system("pause");
}
说明:
数据插入规则:当前结点的左孩子比当前结点值小,当前结点的右孩子比当前结点的值大。
上述二叉树的实际分支情况如下图所示:
输出结果如下图所示:
《二叉树c++实现》 : https://www.cnblogs.com/pandamohist/p/10581907.html
《C++ 二叉树的实现》 : http://ddrv.cn/a/7612