c++实现一个二叉排序树以及树的递归遍历的实现

丶灬走出姿态 提交于 2020-01-17 01:08:39

二叉排序树的理论介绍:

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;
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!