C++ 二叉树的基本操作

1、二叉树基本概念

对于一棵二叉树,有三种基本遍历方式:
1、前序遍历(DLR):先访问根结点,然后遍历左子树,最后遍历右子树。

归结为:从根结点一直从左子树向下直到叶结点,然后返回到叶结点的父亲,再从其父结点的右子树向下。

2、中序遍历(LDR):先中序遍历左子树,然后访问根结点,最后遍历右子树。

3、后序遍历(LRD):先后序遍历左子树,然后遍历右子树,最后访问根结点。

对如上图,遍历结果如下:

前序遍历的结果是ABDEHCFGI

中序遍历的结果是DBEHAFCIG

后序遍历的结果是DHEBFIGCA

2、二叉树的基本性质

3、补充说明

一般情况下,当前结点的左孩子比当前结点值小,当前结点的右孩子比当前结点的值大。

1、插入:

  1.1 插入结点的值比当前结点的值小,继续找当前结点的左子树,

  1.2 插入结点的值比当前结点的值大,继续找当前结点的右子树,

  1.3 找到合适的位置了,插入树。

2、删除:

  2.1 删除结点是叶子结点,直接将其删除即可

  2.2 删除结点只有左孩子或者只有右孩子,将其孩子结点删除,并将指向孩子结点的分支设置为空,c++是设置为NULL。不过更好的做法是,将孩子结点的值替换到当前结点,再删除孩子结点即可。

  2.3 删除的结点同时含有左孩子与右孩子,需要找到删除结点的后继结点,将后继结点作为当前结点。

4、代码实践

#include <iostream>
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");
}

说明:

数据插入规则:当前结点的左孩子比当前结点值小,当前结点的右孩子比当前结点的值大。

上述二叉树的实际分支情况如下图所示:

输出结果如下图所示:

5、参考来源

二叉树c++实现》 : https://www.cnblogs.com/pandamohist/p/10581907.html

《C++ 二叉树的实现》 : http://ddrv.cn/a/7612

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页