二叉樹的基本操作:創建、查找、插入、遍歷、還原二叉樹

1、創建二叉樹的節點(使用指針)
2、二叉樹的查找
3、二叉樹的創建
4、二叉樹的插入操作
5、二叉樹的前序、後序、中序、層序遍歷
6、根據前序遍歷和中序遍歷還原二叉樹
7、根據中序遍歷和後序遍歷還原二叉樹

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

// 二叉樹節點結構體
struct node
{
	int data;		// 數據域
	int layer;		// 當前節點的層次:層序遍歷時,記錄當前層號
	node* lchild;	// 左子樹
	node* rchild;	// 右子樹
};

// 二叉樹節點的創建
node* newNode(int v)
{
	node* Node = new node;
	Node->data = v;
	Node->lchild = Node->rchild = nullptr;
	return Node;
}

// 二叉樹的查找
void searchNode(node* root, int x, int newData)
{
	if (root == nullptr) return;

	if (root->data == x) root->data = newData;

	searchNode(root->lchild, x, newData);
	searchNode(root->rchild, x, newData);
}

// 二叉樹節點的插入
void insertNode(node*& root, int x)
{
	if (root == nullptr)
	{
		root = newNode(x);
		return;
	}

	// 可根據具體性質的不同,選擇插入的條件
	if (root->data > x)
		insertNode(root->lchild, x);
	else
		insertNode(root->rchild, x);
}

// 創建一顆二叉樹
node* CreateNode(vector<int>& v)
{
	node* root = nullptr;
	int len = v.size();
	for (int i = 0; i < len; ++i)
	{
		insertNode(root, v[i]);
	}
	return root;
}

// 先序遍歷:根-左子樹-右子樹
void preorder(node* root)
{
	if (root == nullptr) return;
	printf("%d\n", root->data);
	preorder(root->lchild);
	preorder(root->rchild);
}

// 中序遍歷: 左子樹-根-右子樹
void inorder(node* root)
{
	if (root == nullptr) return;
	preorder(root->lchild);
	printf("%d\n", root->data);
	preorder(root->rchild);
}

// 後序遍歷: 左子樹-右子樹-根
void postorder(node* root)
{
	if (root == nullptr) return;
	preorder(root->lchild);
	preorder(root->rchild);
	printf("%d\n", root->data);
}

// 層序遍歷
void LayerOrder(node* root)
{
	queue<node*> q;
	q.push(root);
	root->layer = 1;	// 根節點位於第一層
	while (!q.empty())
	{
		node* now = q.front();
		q.pop();
		printf("layer = %d, data = %d\n", now->layer, now->data);

		if (now->lchild != nullptr)
		{
			now->lchild->layer = now->layer + 1;	// 左子樹層號
			q.push(now->lchild);
		}
		if (now->rchild != nullptr)
		{
			now->rchild->layer = now->layer + 1;	// 右子樹層號
			q.push(now->rchild);
		}
	}
}

vector<int> preOrder;	  // 先序遍歷數組
vector<int> inOrder;	  // 中序遍歷數組
vector<int> postOrder;    // 後序遍歷數組

// 重建二叉樹:根據二叉樹的先序遍歷和中序遍歷
node* rebuildBinaryTreeFromPreOrderAndInOrder(int preL, int preR, int inL, int inR)
{
	if (preL > preR) return nullptr;

	node* root = new node;
	root->data = preOrder[preL];

	int k;
	for (k = inL; k <= inR; ++k)
	{
		if (inOrder[k] == preOrder[preL])
			break; // 在中序序列中,找到了根節點的位置(根據二叉樹性質不同,比較的方式也不同)
	}

	int numLeft = k - inL; // 左子樹的結點個數

	// 左子樹區間
	root->lchild = rebuildBinaryTreeFromPreOrderAndInOrder(preL + 1, preL + numLeft, inL, k - 1);

	// 右子樹區間
	root->rchild = rebuildBinaryTreeFromPreOrderAndInOrder(preL + numLeft + 1, preR, k + 1, inR);

	return root;
}

// 重建二叉樹:根據二叉樹的中序遍歷和後序遍歷
node* rebuildBinaryTreeFromInOrderAndPostOrder(int inL, int inR, int postL, int postR)
{
	if (postL > postR) return nullptr;

	node* root = new node;
	root->data = postOrder[postR];

	int k;
	for (k = inL; k <= inR; ++k)
	{
		if (inOrder[k] == postOrder[postR])
			break; // 在後序序列中,找到了根節點的位置(根據二叉樹性質不同,比較的方式也不同)
	}

	int numLeft = k - inL; // 左子樹的結點個數

	// 左子樹區間
	root->lchild = rebuildBinaryTreeFromInOrderAndPostOrder(inL, k - 1, postL, postL + numLeft - 1);

	// 右子樹區間
	root->rchild = rebuildBinaryTreeFromInOrderAndPostOrder(k + 1, inR, postL + numLeft, postR - 1);

	return root;
}

int main()
{
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章