二叉排序树,Binary_Sort_Tree,C++完整实现
body, table{font-family: 微软雅黑; font-size: 13.5pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}
| {62,88,58,47,35,73,51,99,37,93}
构造二叉树的目的是为了提高查找和插入、删除关键字的速度。 二叉排序树删除结点的三种情况:
■ 叶子结点(直接删除)
■ 仅有左或右子树的结点(左子树或右子树替换删除节点)
■ 左右子树都有的结点(中序遍历前驱或后继取代该结点)
|
|
| /* BST.h */
#ifndef __BST_H__
#define __BST_H__
#include<iostream>
using namespace std;
typedef struct Binary_Sort_Tree
{
int data;
struct Binary_Sort_Tree* lchild,*rchild;
}bstNode,*pBstNode;
void BST_Insert(pBstNode& root,int data); //二叉排序树中插入结点
bstNode* BST_Search(pBstNode root,int key); //二叉排序树中查找关键字key
int deleteNode(bstNode*& node); //删除节点node,形参为待删除节点的地址本身
int BST_Delete(pBstNode& root,int key); //二叉树删除关键字key //成功返回
/* 二叉搜索树的三种遍历 */
void preorderTraversal_BST(const pBstNode& root);
void inorderTraversal_BST(const pBstNode& root);
void postorderTraversal_BST(const pBstNode& root);
#endif
/* testmain.cpp */
#include"BST.h"
void test()
{
int a[10] = {62,88,58,47,35,73,51,99,37,93};
pBstNode root = nullptr; //建立二叉搜索树
for(int idx=0;idx!=10;++idx)
{
BST_Insert(root,a[idx]);
}
for(int idx=0;idx!=10;++idx)
{
bstNode* ret = BST_Search(root,a[idx]);
if(nullptr!=ret)
cout<<ret->data<<" ";
}
cout<<endl;
cout<<"二叉排序树的三种遍历:"<<endl;
cout<<"前序遍历:";
preorderTraversal_BST(root);
cout<<endl;
cout<<"中序遍历:";
inorderTraversal_BST(root);
cout<<endl;
cout<<"后序遍历:";
postorderTraversal_BST(root);
cout<<endl<<endl;
for(int idx=0;idx!=10;++idx)
{
cout<<"删除"<<a[idx]<<endl;
int ret = BST_Delete(root,a[idx]);
if(-1==ret)
cout<<"BST_Delete "<<a[idx]<<" fail!"<<endl;
cout<<"前序遍历:";
preorderTraversal_BST(root);
cout<<endl;
cout<<"中序遍历:";
inorderTraversal_BST(root);
cout<<endl;
cout<<"后序遍历:";
postorderTraversal_BST(root);
cout<<endl;
}
cout<<endl;
}
int main()
{
test();
system("pause");
}
| /* BST.cpp */
#include"BST.h"
bstNode* BST_Search(pBstNode root,int key) //二叉排序树中查找关键字key
{
if(nullptr==root)
return nullptr;
if(root->data==key)
{
return root;
}
else if(key>root->data) //大于根结点,右子树中继续查找
{
BST_Search(root->rchild,key);
}
else if(key<root->data) //小于根结点,做左子树中继续查找
{
BST_Search(root->lchild,key);
}
}
void BST_Insert(pBstNode& root,int data) //二叉排序树中插入结点
{
if(nullptr==root)
{
root = new bstNode();
root->lchild = root->rchild = nullptr;
root->data = data;
return ;
}
//遍历二叉排序树,找到待插入节点数据的位置
bstNode* parentNode = nullptr; //parentNode永远指向data待插入位置的父结点
bstNode* curNode = root;
while(nullptr!=curNode)
{
parentNode = curNode;
if(data>curNode->data)
curNode = curNode->rchild; //应该插入到右子树
else if(data<=curNode->data)
curNode = curNode->lchild; //应该插入到左子树
}
//找到插入位置
if(data>parentNode->data)
{
bstNode* newNode = new bstNode();
newNode->data = data;
newNode->lchild = nullptr;
newNode->rchild = nullptr;
parentNode->rchild = newNode; //插入到右子树
return ;
}
else
{
bstNode* newNode = new bstNode();
newNode->data = data;
newNode->lchild = nullptr;
newNode->rchild = nullptr;
parentNode->lchild = newNode; //插入到左子树
return ;
}
}
int deleteNode(bstNode*& node)
{//二叉搜索树删除,node的前驱替换
if(nullptr==node)
return -1;
bstNode* delNode = node; //暂存要删除节点
//1、只有一个结点
if(nullptr==node->lchild && nullptr==node->rchild)
{
node = nullptr; //前面这些情况为什么能直接改nullptr?
//下面递归传值的时候传的是root->lchild或者root->rchild,所能是对父结点的左右指针修改。
//而不是类似这种node1(lchild,data,adrnode2)->node2(lchild,data,lchild2),然后传node2,把node2=nullptr,这样到时候遍历根结点就会根据一个野指针adrnode2访问到脏数据
delete delNode;
return 0;
}
//2、只有左孩子,重接左孩子就好
else if (nullptr==node->rchild)
{
node = node->lchild;
delete delNode;
return 0;
}
//3、只有右孩子
else if(nullptr==node->lchild)
{
node = node->rchild;
delete delNode;
return 0;
}
//4、左右孩子都有
else if(nullptr!=node->lchild && nullptr!=node->rchild)
{ //找前驱
bstNode* parent = delNode; //记录父结点
delNode = delNode->lchild;
//待删除节点delNode没有右子树,前驱就是delNode
if(nullptr==delNode->rchild)
{
node->data = delNode->data;
node->lchild = delNode->lchild;
delete delNode;
delNode = nullptr;
return 0;
}
//有右子树,前驱是右子树的最右结点
while(nullptr!=delNode->rchild)
{
parent = delNode;
delNode = delNode->rchild;
}
//找到前驱,开始替换,只要替换结点数据即可,左右孩子关系不能更改
node->data = delNode->data;
//判断前驱是不是要用其他结点替换
parent->rchild = delNode->lchild;
delete delNode;
delNode = nullptr;
return 0;
}
return 0;
}
int BST_Delete(pBstNode& root,int key) //二叉树删除关键字key
{
if(nullptr==root)
return -1;
if(key==root->data)
{
return deleteNode(root);
}
else if(key>root->data)
return BST_Delete(root->rchild,key); //右子树中查找删除
else if(key<root->data)
return BST_Delete(root->lchild,key);
}
/* 二叉搜索树的三种遍历 */
void preorderTraversal_BST(const pBstNode& root)
{
if(nullptr==root)
return;
cout<<root->data<<" ";
preorderTraversal_BST(root->lchild);
preorderTraversal_BST(root->rchild);
}
void inorderTraversal_BST(const pBstNode& root)
{
if(nullptr==root)
return;
inorderTraversal_BST(root->lchild);
cout<<root->data<<" ";
inorderTraversal_BST(root->rchild);
}
void postorderTraversal_BST(const pBstNode& root)
{
if(nullptr==root)
return;
inorderTraversal_BST(root->lchild);
inorderTraversal_BST(root->rchild);
cout<<root->data<<" ";
}
|
二叉排序树,Binary_Sort_Tree,C++完整实现的更多相关文章
- 算法与数据结构(十) 二叉排序树的查找、插入与删除(Swift版)
在上一篇博客中,我们主要介绍了四种查找的方法,包括顺序查找.折半查找.插入查找以及Fibonacci查找.上面这几种查找方式都是基于线性表的查找方式,今天博客中我们来介绍一下基于二叉树结构的查找,也就 ...
- 数据结构图文解析之:树的简介及二叉排序树C++模板实现.
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- 二叉查找树 C++实现(含完整代码)
一般二叉树的查找是通过遍历整棵二叉树实现,效率较低.二叉查找树是一种特殊的二叉树,可以提高查找的效率.二叉查找树又称为二叉排序树或二叉搜索树. 二叉查找树的定义 二叉排序树(Binary Search ...
- c/c++ 二叉排序树
c/c++ 二叉排序树 概念: 左树的所有节点的值(包括子节点)必须小于中心节点,右树所有节点的值(包括子节点)必须大于中心节点. 不允许有值相同的节点. 二叉排序树的特点: 中序遍历后,就是从小到大 ...
- AVL平衡二叉树实现,图解分析,C++描述,完整可执行代码
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- 【Java】 大话数据结构(11) 查找算法(2)(二叉排序树/二叉搜索树)
本文根据<大话数据结构>一书,实现了Java版的二叉排序树/二叉搜索树. 二叉排序树介绍 在上篇博客中,顺序表的插入和删除效率还可以,但查找效率很低:而有序线性表中,可以使用折半.插值.斐 ...
- 二叉排序树的理解和实现(Java)
二叉排序树的定义和性质 二叉排序树又称二叉排序树.它或者是一个空树,或者是一个具有下列性质的二叉树: 若它的左子树不空,则左子树上所有节点的值均小于它的根结构的值 若它的右子树不空,则右子树上所有结点 ...
- 【LeetCode-面试算法经典-Java实现】【109-Convert Sorted List to Binary Search Tree(排序链表转换成二叉排序树)】
[109-Convert Sorted List to Binary Search Tree(排序链表转换成二叉排序树)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 ...
- 数据结构与算法—二叉排序树(java)
前言 前面介绍学习的大多是线性表相关的内容,把指针搞懂后其实也没有什么难度.规则相对是简单的. 再数据结构中树.图才是数据结构标志性产物,(线性表大多都现成api可以使用),因为树的难度相比线性表大一 ...
随机推荐
- xlua修复C#的委托事件的时候,需要提前做好配置
如下所示: //C#静态调用Lua的配置(包括事件的原型),仅可以配delegate,interface [CSharpCallLua] public static List<Type> ...
- Setting the Java Class Path
The class path is the path taht Java Runtime Environment(JRE) searches for classes and other resourc ...
- [Win10]安装msi时2503,2502错误及其解决
简述 刚安装了win10系统,在安装TortoiseGit和TortoiseSvn时,这两个软件是.msi后缀的安装文件,在点击安装时老是提示2503,2502错误,因此无法安装上 搜索了下一般都提到 ...
- python cook 2
迭代器 iterator 生成器 generator 1.手动遍历迭代器 2.代理迭代 解释:将迭代操作代理到容器内部的对象上 操作:使用__iter()__, for 循环遍历对象时,会自动调用 ...
- OnSen UI结合AngularJs打造”美团"APP首页 --Hybrid Ap
1.页面效果图: 演示链接地址:http://www.nxl123.cn/bokeyuan/meiTuanDemo_home/ 2.核心代码 home.html: <ons-page id=&q ...
- 20171113xlVba指定文件夹多簿多表分表合并150
'2017年11月13日 'Next_Seven '功能:文件夹对话框指定文件夹下,合并(复制粘贴)每个Excel文件内的指定子表内容, '在名为"设置"的工作表A列 输入汇总子表 ...
- Confluence 6 对一个空间进行归档后产生的影响
空间 如果一个空间被归档: 将不会在查找结果中显示,除非你选择 在归档空间中查找(Search archived spaces).如果没有归档空间的话,这个功能是隐藏的. 页面和内容将不会在 Conf ...
- IntelliJ IDEA的调试方法
快捷键F9 resume programe 恢复程序 Alt+F10 show execution point 显示执行断点 F8 S ...
- 2018-2019 ACM-ICPC Brazil Subregional Programming Contest
A:留坑 B:二维sg函数,特判边界情况 //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pragma GCC optimize(4) / ...
- 【JS】【4】字符串数字比较大小
两个转换函数: parseInt():把值转换成整数 parseFloat():把值转换成浮点数 也有其他方法,详情请看参考博客,但个人认为转换函数是最好的方法 参考文档: 1,js.jquery字符 ...