文章目录
(一)二叉搜索树(BST)
【前言】上一篇中的二叉树是用直接赋值创建的,数据量很小,一但数据量变大,那个方法肯定不适用。
所以,为了高效的创建一个二叉树,就有了插入法创建二叉树;
二叉搜索树(BST):Binary Search Tree的首字母大写构成。
【特点】:它是一个特殊的二叉树,树中的结点必须满足:根节点的值大于左子树的值且小于右子树的值。即:根>左,根<右。
下面,我们来看二叉树的建立:
1.使用结构体变量构建树
我们知道,二叉树的结点不仅包括数据,还包含指向子节点的指针。所以,每个结点就应该用结构体实现。
typedef struct node
{
int data; //结点的数据
struct node* left; //此结点的左子结点的结构体指针
struct node* right;
}Node
2.打包整颗树
上一篇中的树很散乱,为了看起来方便,我们将整个树形结构打包成一棵树。
typedef struct
{
Node* root;
}Tree;
3.插入法创建树(重点)
可以将这一步分为以下几个小步来实现:
3.1 将一个数据打包成一个结点
树是又结点组成的。所以,我们需要将一个数据打包成一个结点,以便于下面的操作。
使用malloc函数开辟一个Node类型的新结点,将它的左右子树都置空;注:malloc函数在头文件
#include<cstdlib>中
Node* node = (Node*)malloc(sizeof(Node)); //创建一个新的结点;
node->data = value;
node->left = NULL;
node->right = NULL;
3.2 创建第一个根节点
将第一个数据作为一个根节点;
if (tree->root == NULL) //如果此时这个树的根节点为空的话,就让它做根节点;
{
tree->root = node;
}
3.3 创建后续结点
与根节点比较,如果比它小,就放进左边,如果左边还有数据,就把左边的数据当做根节点继续比较。如果比它大,就放进右边,如果右边还有数据,就把右边的数据当做根节点继续比较。
可以看到,这是一个while的过程。为了不使他的根节点发生变化,我们可以定义一个临时的Node类型的变量代替执行操作;
else
{
Node* temp = tree->root; //定义一个临时结构体变量指向此时结点的根节点,用这个临时指针进行接下来的插入操作;
while (temp != NULL)
{
if (value < temp->data) //插入到左边;
{
if (temp->left == NULL) //如果左边为空,直接插入;
{
temp->left = node;
return; //终止;
}
else
{
temp = temp->left; //如果左边不为空,继续往下找;
}
}
else
{ //插入到右边;
if (temp->right == NULL) //如果右边为空,直接插入;
{
temp->right = node;
return;
}
else
{
temp = temp->right; //如果右边不为空,继续往下找;
}
}
}
}
3.4 二叉搜索树的高度
树的高度=max(左子树高度,右子树高度)+1;
可以通过递归求其高度。
int get_hight(Node* node)//求树的高度;
{
if (node == NULL) //递归出口,如果它的结点为空,则高度为0;
{
return 0;
}
else
{
int left = get_hight(node->left); //递归求左子树高度
int right = get_hight(node->right); //递归求右子树高度
int max = left; //判断左右子树高度的最大值
if (right > max)
{
max = right;
}
return max + 1;//树的高度=max(左子树高度,右子树高度)+1;
}
}
3.5 二叉搜索树中的最大值
在二叉搜索树中求最大值,可以直接找叶子结点的最右边的值,它就是最大的数。
一般的树中,求最大值。可以求左子树的最大值,右子树的最大值,和根节点值比较,三者最大者即为树的最大值,这种方法也适应于二叉搜索树。
用递归实现;
int max(Node* node) //普通树求最大值,也适应与二叉搜索树,二叉搜索树也可以直接找最右边的值,它就是最大值;
{
int maxleft; //假设所有结点都是正数;
int maxright;
int maxroot;
if (node == NULL)
{
return -1;
}
else
{
maxleft = max(node->left);
maxright = max(node->right);
maxroot = node->data;
int max1;
max1 = maxleft;
if (max1< maxright)
{
max1 = maxright;
}
if (max1<maxroot)
{
max1 = maxroot;
}
return max1;
}
}
到此,一个树形结构就创建完成了;
可以用前序遍历,中序遍历,后序遍历进行输出。
注意::二叉搜索树的中序遍历是从小大一个有序的数据列;
完整代码实现如下:
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct node
{
int data; //结点的数据
struct node* left; //此结点的左子结点的结构体指针
struct node* right;
}Node;
typedef struct
{
Node* root;
}Tree;
void insert(Tree* tree, int value)
{
Node* node = (Node*)malloc(sizeof(Node)); //创建一个新的结点;
node->data = value;
node->left = NULL;
node->right = NULL;
if (tree->root == NULL) //如果此时这个树的根节点为空的话,就让它做根节点;
{
tree->root = node;
}
else
{
Node* temp = tree->root; //定义一个临时结构体变量指向此时结点的根节点,用这个临时指针进行接下来的插入操作;
while (temp != NULL)
{
if (value < temp->data) //插入到左边;
{
if (temp->left == NULL) //如果左边为空,直接插入;
{
temp->left = node;
return; //终止;
}
else
{
temp = temp->left; //如果左边不为空,继续往下找;
}
}
else
{ //插入到右边;
if (temp->right == NULL) //如果右边为空,直接插入;
{
temp->right = node;
return;
}
else
{
temp = temp->right; //如果右边不为空,继续往下找;
}
}
}
}
}
void preorder(Node* p1) //前序遍历;
{
if (p1 != NULL)
{
printf("%d\n", p1->data);
preorder(p1->left);
preorder(p1->right);
}
}
void inorder(Node* p2) //中序遍历,从小到大排序
{
if (p2 != NULL)
{
inorder(p2->left);
printf("%d\n", p2->data);
inorder(p2->right);
}
}
void postorder(Node* p3)//后序遍历;
{
if (p3 != NULL)
{
postorder(p3->left);
postorder(p3->right);
printf("%d\n", p3->data);
}
}
int get_hight(Node* node)//求树的高度;
{
if (node == NULL) //递归出口,如果它的结点为空,则高度为0;
{
return 0;
}
else
{
int left = get_hight(node->left); //递归求左子树高度
int right = get_hight(node->right); //递归求右子树高度
int max = left; //判断左右子树高度的最大值
if (right > max)
{
max = right;
}
return max + 1;//树的高度=max(左子树高度,右子树高度)+1;
}
}
int max(Node* node) //普通树求最大值,也适应与二叉搜索树,二叉搜索树也可以直接找最右边的值,它就是最大值;
{
int maxleft; //假设所有结点都是正数;
int maxright;
int maxroot;
if (node == NULL)
{
return -1;
}
else
{
maxleft = max(node->left);
maxright = max(node->right);
maxroot = node->data;
int max1;
max1 = maxleft;
if (max1< maxright)
{
max1 = maxright;
}
if (max1<maxroot)
{
max1 = maxroot;
}
return max1;
}
}
int main()
{
int a[7] = { 6,3,8,2,5,1,7 };
Tree tree; //定义一个树形变量;
tree.root = NULL; //开始时,它的根节点初始为空;
for (int i = 0; i<7; i++)
{
insert(&tree, a[i]);
}
cout << "先序遍历:" << endl;
preorder(tree.root);
cout << "中序遍历:" << endl;
inorder(tree.root);
cout << "树的高度:";
cout << get_hight(tree.root) << endl;
cout << "树的最大值:";
cout << max(tree.root) << endl;
return 0;
}
二叉树的操作还有:
【插入】
【删除】
【查找】
这一篇中树中的数据都假设没有重复的且没有负值。
待更。。。。。。。。