原理
最近学习数据结构相关知识,重点回顾了二叉树的创建与搜索。
如下图所示,是一棵二叉树。
图1 二叉树
有了这样一颗二叉树,就需要了解一些基本概念:
- 深度
- 子节点
- 键值
其中,深度就是二叉树的层数,从上往下数,如图1中有深度为3;图中一个圆圈代表一个节点;节点内的数值为键值,分别为4;2;7;1;3。
而4所在的节点称为根节点;而2、7所在的节点为根节点的子节点。
代码
有了这些知识,我们就可以创建二叉树,使用递归创建,上代码
// 节点数据结构
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
void CreateTree(Node &T)
{
string input_;
int val;
cout << "请输入:" << endl;
cin >> input_;
if (input_ != "*")
{
//val = atoi(input_.data())亦可
val = atoi(input_.c_str());
T = new TreeNode(val);
CreateTree(T->left);
CreateTree(T->right);
}
else
{
T = NULL;
}
}
如图1中的二叉树,依次输入4->2->1-> * -> * ->3-> * -> * ->7-> * -> *
至此,二叉树创建完成,当然其中要注意的是,因为我们要操作的是节点指针,所以我们要用到高一层次的指针或者同级引用,否则无法修改对应的节点指针,可能还会造成野指针问题(查阅资料:大致就是使用了未初始化的指针),可以简单记为:操作什么数据类型则使用高一层次的指针或者引用,指针本身也是一种类型。既然创建完成,必要就是进行搜索操作,还是用递归算法进行遍历(中序遍历)
void InoderTreeWalker(TreeNode *root)
{
if (root != NULL)
{
InoderTreeWalker(root->left);
cout << root->val <<" ";
InoderTreeWalker(root->right);
}
}
以上面创建的二叉树为例,结果为1 2 3 4 7
可以验证,这种遍历复杂的为O(n),n为节点数
既然,完成了遍历,那么搜索也是必要的:
TreeNode* searchBST(TreeNode* root, int val) {
if (root == NULL || root->val ==val)
return (root);
if (val < root->val)
return (searchBST( root->left, val));
else
return (searchBST( root->right,val));
}
这样就实现了给定键值,在二叉树上的搜索,可以知道这是一条路径的搜索,复杂的正比于树高度\深度,为O(h).