二叉排序树的理论介绍:
https://baike.baidu.com/item/%E4%BA%8C%E5%8F%89%E6%8E%92%E5%BA%8F%E6%A0%91/10905079?fr=aladdin
一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的结点。
二叉排序树的节点类定义:
class node_data{
public:
int data;//数据域
node_data *parent, *left, *right;//每个节点有3个指针,分别指向父节点,左节点和右节点
node_data() :data(0), parent(NULL), left(NULL), right(NULL){};//默认构造函数
node_data(int in_data) :data(in_data), parent(NULL), left(NULL), right(NULL) {};//产生一个节点
};
二叉排序树的类定义:
class binary_tree{
public:
binary_tree(int num[], int len);//调用构造函数的时候,\
就可以生成相对应大小的二叉树,构造方法中调用的是递归或者非递归的方式生成二叉树
void insert_node(int data);//非递归的方式插入一个节点
void insert_node_recursive(int data);//递归的方式插入一个节点,\
递归的时候是通过调用下面private成员中的方法insert_node_recu
void delete_node(int data);//递归的方式删除一个节点及其之下的所有左右子树的节点,\
递归的时候是通过调用下面private成员中的方法delete_node_recu
node_data *search_node(int data);//递归的方式查找一个节点,\
递归的时候是通过调用下面private成员中的方法search_node_recu
void print_tree(void);
private:
node_data *root; //根节点
void insert_node_recu(node_data *current, int data);//具体实现递归插入方法
void delete_node_recu(node_data *current);//递归实现删除的方法
node_data *search_node_recu(node_data *current, int data);//data递归实现查找的方法
void print_tree_ldr_recu(node_data *current);//使用递归的方法中序遍历
};
二叉排序树的插入:
对二叉排序树的插入分为递归和非递归的方法
binary_tree::binary_tree(int num[], int len)
{
root = new node_data();
for (int i = 1; i < len; i++)
{
insert_node(num[i]);//非递归的方式
//insert_node_recursive(num[i]);//递归的方式
}
}
void binary_tree::insert_node(int data)
{
node_data *node = new node_data(data);
node_data *p, *cur;
p = cur = root;
while (p != NULL)
{
cur = p;
if (p->data > data){
p = p->left;
}
else if (p->data < data){
p = p->right;
}
else{
delete node;
return;
}
}
node->parent = cur;
if (cur->data > data)
cur->left = node;
else
cur->right = node;
}
void binary_tree::insert_node_recursive(int data)
{
if (root != NULL)
insert_node_recu(root, data);//使用递归的操作的方法
}
void binary_tree::insert_node_recu(node_data *current, int data)
{
if (current->data < data){//在节点current的右子树插入
if (current->right == NULL){//到右子树的叶节点
current->right = new node_data(data);//新生成节点并插入到当前节点的右节点
current->right->parent = current;//新生成的节点的父节点是当前的节点
}
else{
insert_node_recu(current->right, data);//递归直到叶子节点
}
}
else if (current->data > data){//在节点的左子树插入,操作同上
if (current->left == NULL){
current->left = new node_data(data);
current->left->parent = current;
}
else{
insert_node_recu(current->left, data);
}
}
}
树的遍历:
树的遍历分为前序遍历,中序遍历和后序遍历。最接单的实现方式就是递归的方式了。代码如下:
void binary_tree::print_tree(void)
{
if (root != NULL){
//print_tree_ldr_recu(root);
print_tree_dlr_recu(root);
//print_tree_lrd_recu(root);
}
}
void binary_tree::print_tree_ldr_recu(node_data *current)
{
if (current != NULL){
print_tree_ldr_recu(current->left);
cout << current->data << " ";
print_tree_ldr_recu(current->right);
}
}
void binary_tree::print_tree_dlr_recu(node_data *current)
{
if (current != NULL){
cout << current->data << " ";
print_tree_dlr_recu(current->left);
print_tree_dlr_recu(current->right);
}
}
void binary_tree::print_tree_lrd_recu(node_data *current)
{
if (current != NULL){
print_tree_lrd_recu(current->left);
print_tree_lrd_recu(current->right);
cout << current->data << " ";
}
}
完整的测试代码:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
// test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#pragma warning(disable:4996)
#include <string>
using namespace std;
class node_data{
public:
int data;//数据域
node_data *parent, *left, *right;//每个节点有3个指针,分别指向父节点,左节点和右节点
node_data() :data(0), parent(NULL), left(NULL), right(NULL){};//默认构造函数
node_data(int in_data) :data(in_data), parent(NULL), left(NULL), right(NULL) {};//产生一个节点
};
class binary_tree{
public:
binary_tree(int num[], int len);//调用构造函数的时候,\
就可以生成相对应大小的二叉树,构造方法中调用的是递归或者非递归的方式生成二叉树
void insert_node(int data);//非递归的方式插入一个节点
void insert_node_recursive(int data);//递归的方式插入一个节点,\
递归的时候是通过调用下面private成员中的方法insert_node_recu
void delete_node(int data);//递归的方式删除一个节点及其之下的所有左右子树的节点,\
递归的时候是通过调用下面private成员中的方法delete_node_recu
node_data *search_node(int data);//递归的方式查找一个节点,\
递归的时候是通过调用下面private成员中的方法search_node_recu
void print_tree(void);
private:
node_data *root; //根节点
void insert_node_recu(node_data *current, int data);//具体实现递归插入方法
void delete_node_recu(node_data *current);//递归实现删除的方法
node_data *search_node_recu(node_data *current, int data);//data递归实现查找的方法
void print_tree_ldr_recu(node_data *current);//使用递归的方法中序遍历
void print_tree_dlr_recu(node_data *current);//使用递归的方法先序遍历
void print_tree_lrd_recu(node_data *current);//使用递归的方法后序遍历
};
binary_tree::binary_tree(int num[], int len)
{
root = new node_data(num[0]);
for (int i = 1; i < len; i++)
{
insert_node(num[i]);//非递归的方式
//insert_node_recursive(num[i]);//递归的方式
}
}
void binary_tree::insert_node(int data)
{
node_data *node = new node_data(data);
node_data *p, *cur;
p = cur = root;
while (p != NULL)
{
cur = p;
if (p->data > data){
p = p->left;
}
else if (p->data < data){
p = p->right;
}
else{
delete node;
return;
}
}
node->parent = cur;
if (cur->data > data)
cur->left = node;
else
cur->right = node;
}
void binary_tree::insert_node_recursive(int data)
{
if (root != NULL)
insert_node_recu(root, data);//使用递归的操作的方法
}
void binary_tree::insert_node_recu(node_data *current, int data)
{
if (current->data < data){//在节点current的右子树插入
if (current->right == NULL){//到右子树的叶节点
current->right = new node_data(data);//新生成节点并插入到当前节点的右节点
current->right->parent = current;//新生成的节点的父节点是当前的节点
}
else{
insert_node_recu(current->right, data);//递归直到叶子节点
}
}
else if (current->data > data){//在节点的左子树插入,操作同上
if (current->left == NULL){
current->left = new node_data(data);
current->left->parent = current;
}
else{
insert_node_recu(current->left, data);
}
}
}
node_data *binary_tree::search_node(int data)
{
if (root != NULL)
return search_node_recu(root, data);
return NULL;
}
node_data *binary_tree::search_node_recu(node_data *current, int data)//方法的思路为,比较current中额数据和data的大小
{
if (current->data > data){
if (current->left == NULL)
return NULL;
else
return search_node_recu(current->left, data);
}
else if (current->data < data){
if (current->right == NULL)
return NULL;
else
return search_node_recu(current->right, data);
}
return current;//相等,current就是要查找的节点
}
void binary_tree::delete_node(int data)//删除数据为data的节点以及它的子树
{
node_data *p_node = search_node(data);
if (p_node != NULL){
delete_node_recu(p_node);
}
}
void binary_tree::delete_node_recu(node_data *current)
{
if (current->left != NULL)
delete_node_recu(current->left);
if (current->right != NULL)
delete_node_recu(current->right);
if (current->parent == NULL){//current是根节点
delete current;
root = NULL;
return;
}
//删除叶子节点
if (current->parent->data > current->data)//current是左节点
current->parent->left = NULL;//将父节点的左指针NULL
else if (current->parent->data < current->data)//同上
current->parent->right = NULL;
delete current;//删除current节点
}
void binary_tree::print_tree(void)
{
if (root != NULL){
//print_tree_ldr_recu(root);
print_tree_dlr_recu(root);
//print_tree_lrd_recu(root);
}
}
void binary_tree::print_tree_ldr_recu(node_data *current)
{
if (current != NULL){
print_tree_ldr_recu(current->left);
cout << current->data << " ";
print_tree_ldr_recu(current->right);
}
}
void binary_tree::print_tree_dlr_recu(node_data *current)
{
if (current != NULL){
cout << current->data << " ";
print_tree_dlr_recu(current->left);
print_tree_dlr_recu(current->right);
}
}
void binary_tree::print_tree_lrd_recu(node_data *current)
{
if (current != NULL){
print_tree_lrd_recu(current->left);
print_tree_lrd_recu(current->right);
cout << current->data << " ";
}
}
int main()
{
int num[] = {5,3,7,2,4,6,8,1};
binary_tree my_tree(num, 8);
cout << "ldr output: ";
my_tree.print_tree();
cout << endl;
node_data *p = my_tree.search_node(6);
cout << "search data:" << p->data << endl;
//my_tree.print_tree();
cout << endl;
#if 0
my_tree.delete_node(5);
my_tree.print_tree();
cout << endl;
my_tree.delete_node(6);
my_tree.print_tree();
cout << endl;
my_tree.delete_node(8);
my_tree.print_tree();
cout << endl;
my_tree.delete_node(8);
my_tree.print_tree();
cout << endl;
my_tree.insert_node(21);
my_tree.print_tree();
cout << endl;
my_tree.insert_node_recursive(6);
my_tree.print_tree();
cout << endl;
#endif
return 0;
}
来源:CSDN
作者:酸菜鱼的鱼
链接:https://blog.csdn.net/u010299133/article/details/103965210