ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二叉搜索树 的实现

2021-09-23 12:58:22  阅读:160  来源: 互联网

标签:node return 实现 二叉 搜索 stack Btree root 节点


什么是二叉搜索树?二叉搜索树有什么特性?二叉搜索树是怎样实现的?

1:二叉搜索树 又称二叉查找树、二叉排序树,顾名思义二叉搜索树的查找效率非常的高,而且二叉搜索树要满足二叉树的结构特性故每个根节点最多只有两个叶子节点。这的二叉搜索树和前面学的堆的结构也是相似的。

树的图像结构:

 2:二叉搜索树的特性:由上面的二叉树结构图像可以看出左子节点的值要比根节点小而右子节点的值要比根节点大,每一棵子树都是这样,这就是搜索二叉树的特性。

1)若左子树不空,则左子树上所有节点的值均小于或等于它的根节点的值;

2)若右子树不空,则右子树上所有节点的值均大于或等于它的根节点的值;

3)左、右子树也分别为二叉排序树

3:二叉搜索树的实现

二叉搜索树的构建也是跟据其特性构建的,构建的二叉搜索树要将每个子节点连接在父节点上,所以要定义两指针一个为右子节点指针指向右字节点,另一个为左子节点指针指向左子节点。

代码实现:

typedef struct binaryTree {
	elemStyle date;
	struct binaryTree* leftChild;
	struct binaryTree* rightChild;
}Btree;

表示树的结构体定义完以后我们要做的是构建一颗二叉搜索树

//在二叉搜索树中插入节点
bool insertBinaryTree(Btree** root, Btree* node) {
	Btree* tmp, * father = NULL;
	if (!node) {
		return false;//节点没有分配内存
	}
	else {
		node->leftChild = NULL;
		node->rightChild = NULL;
	}

	if (*root) {
		tmp = *root;
	}
	else {
		*root = node;
		return true;
	}

	while (tmp) {
		father = tmp;
		if (compare(tmp->date, node->date)) {
			tmp = tmp->rightChild;
		}
		else {
			tmp = tmp->leftChild;
		}
	}
	if (compare(father->date, node->date)) {
		father->rightChild = node;
	}
	else {
		father->leftChild = node;
	}
	return true;
}

构建的思路:跟据二叉搜索树的特性,左字节点一定小于等于根节点,右字节点一定大于等于根节点。如果没有根节点那么就将第一个节点作为根节点并返回,如果有根节点那么就判断根节点和入树的节点哪个的值要大,如果根节点的值大于当前的值那么就锁定到右字节点上否则就锁定到左子节点上,继续循环比较直到根节点指向的子节点为空,将当前节点连接到根节点上,新入树的节点也是这样操作。

树构建好以后要左的是遍历树,前序遍历树的实现我们用栈实现

//前序遍历二叉树
void ergodicBinaryTree(Btree* root) {
	if (!root)return;
	Stack stack;
	initStack(stack);
	Btree tmp;
	enterStack(stack, *root);
	cout << "树中的元素有:";

	while (stack.top != stack.base) {
		outStack(stack, tmp);
		cout << tmp.date << "  ";
		if (tmp.rightChild) {
			enterStack(stack, *tmp.rightChild);
		}
		if (tmp.leftChild) {
			enterStack(stack, *tmp.leftChild);
		}
	}
	destoryStack(stack);
}

实现的具体思路:

在之前已经将树构建好了,所以第一步要做的就是将第一个节点入栈,判断它两个子节点是否为空,将不为空的节点入栈,进行了依次循环后将最后入栈的节点出栈,再判断该节点的子节点是否为空不为空则继续入栈,连续进行此操作就可以实现树种元素的打印

删除树中的节点,递归实现,所以如果要想看懂这操作要看得懂递归

//删除树的节点
Btree* deleteBinaryTree(Btree* root, elemStyle index, Btree*& node) {
	//树中没有这个节点
	if (root == NULL)return NULL;
	if (compare(root->date, index)) {
		root->rightChild = deleteBinaryTree(root->rightChild, index, node);
		return root;
	}
	if (compare(index, root->date)) {
		root->leftChild = deleteBinaryTree(root->leftChild, index, node);
		return root;
	}
	node = root;
	//左右子节点都为空
	if (!root->leftChild && !root->rightChild)return NULL;
	//左节点为空右节点不为空
	if (!root->leftChild && root->rightChild)return root->rightChild;
	//右节点为空左节点不为空
	if (!root->rightChild && root->leftChild)return root->leftChild;
	//左右节点都不为空
	root->date = findBinaryTree(root->leftChild);
	root->leftChild = deleteBinaryTree(root->leftChild, root->date, node);
	return root;
}

//找到最大节点
elemStyle findBinaryTree(Btree* node) {
	while (node->rightChild) {
		node = node->rightChild;
	}
	return node->date;
}

由于该操做的逻辑比较复杂就不再讲解

据体代码实现

#pragma once
#include<iostream>

using namespace std;

typedef int elemStyle;
#define MAX_SIZE 28

typedef struct binaryTree {
	elemStyle date;
	struct binaryTree* leftChild;
	struct binaryTree* rightChild;
}Btree;

typedef struct _stack {
	Btree* top;
	Btree* base;
}Stack;

bool initStack(Stack& stack); //初始化栈
void enterStack(Stack& stack, Btree treeNode);//将元素入栈
void outStack(Stack& stack, Btree& tree);//将元素出栈
void destoryStack(Stack& stack);//销毁栈

//初始化栈
bool initStack(Stack& stack) {
	stack.base = new Btree[MAX_SIZE];
	if (!stack.base)return false;
	stack.top = stack.base;
	return true;
}

//将元素入栈
void enterStack(Stack& stack, Btree treeNode) {
	if (stack.top - stack.base == MAX_SIZE)return;
	*(stack.top++) = treeNode;
	return;
}

//将元素出栈
void outStack(Stack& stack, Btree& tree) {
	if (stack.top == stack.base)return;
	tree = *(--stack.top);
	return;
}

//销毁栈
void destoryStack(Stack& stack) {
	if (stack.base) {
		delete stack.base;
		stack.top = NULL;
		stack.base = NULL;
	}
}
#pragma once
#include"_stack.h"

#define compare(a,b) (a < b)
#define equal(a,b) (a == b)

bool insertBinaryTree(Btree** root, Btree* node);//在二叉搜索树中插入节点
void ergodicBinaryTree(Btree* root);//遍历二叉树
Btree* deleteBinaryTree(Btree* root, elemStyle index, Btree*& node);//删除树的节点
elemStyle findBinaryTree(Btree* node);//找到最大节点

//在二叉搜索树中插入节点
bool insertBinaryTree(Btree** root, Btree* node) {
	Btree* tmp, * father = NULL;
	if (!node) {
		return false;//节点没有分配内存
	}
	else {
		node->leftChild = NULL;
		node->rightChild = NULL;
	}

	if (*root) {
		tmp = *root;
	}
	else {
		*root = node;
		return true;
	}

	while (tmp) {
		father = tmp;
		if (compare(tmp->date, node->date)) {
			tmp = tmp->rightChild;
		}
		else {
			tmp = tmp->leftChild;
		}
	}
	if (compare(father->date, node->date)) {
		father->rightChild = node;
	}
	else {
		father->leftChild = node;
	}
	return true;
}

//前序遍历二叉树
void ergodicBinaryTree(Btree* root) {
	if (!root)return;
	Stack stack;
	initStack(stack);
	Btree tmp;
	enterStack(stack, *root);
	cout << "树中的元素有:";

	while (stack.top != stack.base) {
		outStack(stack, tmp);
		cout << tmp.date << "  ";
		if (tmp.rightChild) {
			enterStack(stack, *tmp.rightChild);
		}
		if (tmp.leftChild) {
			enterStack(stack, *tmp.leftChild);
		}
	}
	destoryStack(stack);
}

//删除树的节点
Btree* deleteBinaryTree(Btree* root, elemStyle index, Btree*& node) {
	//树中没有这个节点
	if (root == NULL)return NULL;
	if (compare(root->date, index)) {
		root->rightChild = deleteBinaryTree(root->rightChild, index, node);
		return root;
	}
	if (compare(index, root->date)) {
		root->leftChild = deleteBinaryTree(root->leftChild, index, node);
		return root;
	}
	node = root;
	//左右子节点都为空
	if (!root->leftChild && !root->rightChild)return NULL;
	//左节点为空右节点不为空
	if (!root->leftChild && root->rightChild)return root->rightChild;
	//右节点为空左节点不为空
	if (!root->rightChild && root->leftChild)return root->leftChild;
	//左右节点都不为空
	root->date = findBinaryTree(root->leftChild);
	root->leftChild = deleteBinaryTree(root->leftChild, root->date, node);
	return root;
}

//找到最大节点
elemStyle findBinaryTree(Btree* node) {
	while (node->rightChild) {
		node = node->rightChild;
	}
	return node->date;
}

标签:node,return,实现,二叉,搜索,stack,Btree,root,节点
来源: https://blog.csdn.net/qq_55164622/article/details/120430354

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有