数据结构——二叉搜索树
一、定义
二叉搜索树(binary search tree),又叫二叉查找树、二叉排序树。若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势;所以应用十分广泛,例如在文件系统和数据库系统一般会采用这种数据结构进行高效率的排序与检索操作。
二、特性
在二叉搜索树中:
1.若任意结点的左子树不空,则左子树上所有结点的值均不大于它的根结点的值。
2. 若任意结点的右子树不空,则右子树上所有结点的值均不小于它的根结点的值。
3.任意结点的左、右子树也分别为二叉搜索树。
三、操作
BStree *insertBST(BStree *pBST,Elementtype value);//递归插入
BStree *insertBST1(BStree *pBST,Elementtype value);//非递归插入
BStree *delBST(BStree *pBST,Elementtype value);//递归删除
BStree *delBST1(BStree *pBST,Elementtype value);//非递归删除
BStree *min(BStree *pBST);//取树中最小值
BStree *max(BStree *pBST);//取树中最大值
void cleanBST(BStree **pBST);//清空树
void Preordertraversal(BStree *pBST);//前序遍历
void Inordertraversal(BStree *pBST);//中序遍历
void Postordertraversal(BStree *pBST);//后续遍历
四、时间复杂度
不论哪一种操作,所花的时间都和树的高度成正比。因此,如果共有n个元素,那么平均每次操作需要O(logn)的时间。
五、算法实现
二叉排序树的操作主要有:
1.查找:递归查找是否存在key。
2.插入:原树中不存在key,插入key返回true,否则返回false。
3.构造:循环的插入操作。
4.删除:(1)叶子节点:直接删除,不影响原树。
(2)仅仅有左或右子树的节点:节点删除后,将它的左子树或右子树整个移动到删除节点的位置就可以,子承父业。
(3)既有左又有右子树的节点:找到须要删除的节点p左子树上的最大值或者右子树上的最小值,赋给p,然后删除该最大值或者最小值节点。
上代码:
头文件:
#include <stdio.h>
#include <stdlib.h>
#ifndef BSTREE_H
#define BSTREE_H
typedef struct node BStree;
typedef int Elementtype;
struct node{Elementtype value;BStree *left;BStree *right;
};
#endif
BStree *insertBST(BStree *pBST,Elementtype value);//递归插入
BStree *insertBST1(BStree *pBST,Elementtype value);//非递归插入
BStree *delBST(BStree *pBST,Elementtype value);//递归删除
BStree *delBST1(BStree *pBST,Elementtype value);//非递归删除BStree *min(BStree *pBST);//取树中最小值
BStree *max(BStree *pBST);//取树中最大值
void cleanBST(BStree **pBST);//清空树void Preordertraversal(BStree *pBST);
void Inordertraversal(BStree *pBST);
void Postordertraversal(BStree *pBST);
函数实现代码 :
#include "BStree.h"//typedef struct node BStree;
//typedef int Elementtype;
//struct node{
// Elementtype value;
// BStree *left;
// BStree *right;
//};BStree *insertBST(BStree *pBST,Elementtype value){//递归插入if(!pBST){BStree *pNode=(BStree*)malloc(sizeof(BStree));pNode->value=value;pNode->left=pNode->right=NULL;pBST=pNode;}else{if(value<pBST->value){pBST->left=insertBST(pBST->left,value);}else if(value>pBST->value){pBST->right=insertBST(pBST->right,value);}}return pBST;
}
BStree *insertBST1(BStree *pBST,Elementtype value){//非递归插入 BStree *ptemp=pBST;BStree *pNode=(BStree*)malloc(sizeof(BStree));pNode->value=value;pNode->left=pNode->right=NULL;BStree *parent=NULL;if(!pBST){ptemp=pNode;}else{while(pBST){parent=pBST;if(value<pBST->value){pBST=pBST->left;if(!pBST) parent->left=pNode;}else if(value>pBST->value){pBST=pBST->right;if(!pBST) parent->right=pNode;}}}return ptemp;
}
BStree *delBST(BStree *pBST,Elementtype value){//递归删除 if(pBST){if(value<pBST->value){pBST->left=delBST(pBST->left,value);}else if(value>pBST->value){pBST->right=delBST(pBST->right,value);}else{if(pBST->left&&pBST->right){BStree *ptemp=min(pBST->right);pBST->value=ptemp->value;pBST->right=delBST(pBST->right,ptemp->value);}else if(!pBST->left){BStree *ptemp=pBST;pBST=pBST->right;free(ptemp);}else if(!pBST->right){BStree *ptemp=pBST;pBST=pBST->left;free(ptemp);}}}return pBST;
}
/*非递归删除,当找到欲删除结点ptemp时需同时记录父节点parent,删除后将parent和ptemp的后续节点链接*/
BStree *delBST1(BStree *pBST,Elementtype value){//非递归删除BStree *parent=NULL;BStree *ptemp=pBST;while(ptemp){//循环条件ptemp不为空,当欲删除值不存在则ptemp最终为空 parent=ptemp;//记录当前节点的父节点 if(value<ptemp->value){//value小于当前节点值,向左查找 ptemp=ptemp->left;}else if(value>ptemp->value){//反之向右查找 ptemp=ptemp->right;}if(ptemp&&ptemp->value==value){//ptemp不为空,且value等于当前节点值,需要考虑节点同时有左右子树,左子树为空,右子树为空三种情况 if(!ptemp->left){if(parent->left==ptemp){parent->left=ptemp->right;free(ptemp);}else if(parent->right==ptemp){parent->right=ptemp->right;free(ptemp); }}else if(!ptemp->right){if(parent->left==ptemp){parent->left=ptemp->left;free(ptemp);}else if(parent->right==ptemp){parent->right=ptemp->left;}}else if(ptemp->left&&ptemp->right){//当同时有左右子树,可转换为删除右子树上的最小值或者左子树上的最大值 BStree *p=min(ptemp->right);ptemp->value=p->value;BStree *q=ptemp->right;parent=ptemp;while(q->value!=p->value){parent=q;q=q->left;}if(q==ptemp->right) parent->right=q->right;//父节点位于右子树上父节点为ptemp两种情况 else parent->left=q->right;free(q);break;//此种情况删除了其他节点代替了ptemp,需要break跳出循环。 }}}if(!ptemp){printf("删除值不存在\n");}return pBST;
} BStree *min(BStree *pBST){//取树中最小值 if(pBST){while(pBST->left){pBST=pBST->left;}return pBST;}
}
BStree *max(BStree *pBST){//取树中最大值if(pBST){while(pBST->right){pBST=pBST->right;}return pBST;}
}
void cleanBST(BStree **pBST){//清空树 if(*pBST){cleanBST(&(*pBST)->left);cleanBST(&(*pBST)->right);free(*pBST);*pBST=NULL;}
}
/*遍历验证程序*/
void Preordertraversal(BStree *pBST){if(pBST){printf("%d ",pBST->value);Preordertraversal(pBST->left);Preordertraversal(pBST->right);}
}
void Inordertraversal(BStree *pBST){if(pBST){Inordertraversal(pBST->left);printf("%d ",pBST->value);Inordertraversal(pBST->right);}
}
void Postordertraversal(BStree *pBST){if(pBST){Postordertraversal(pBST->left);Postordertraversal(pBST->right);printf("%d ",pBST->value);}
}
main函数 :
#include <stdio.h>
#include <stdlib.h>
#include "BStree.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */int main(int argc, char *argv[]) {BStree *pBST=NULL;Elementtype value;scanf("%d",&value);while(value!=-1){pBST=insertBST1(pBST,value);scanf("%d",&value);}pBST=delBST(pBST,9);pBST=delBST1(pBST,5); pBST=delBST1(pBST,9);Preordertraversal(pBST);printf("\n");Inordertraversal(pBST);printf("\n");Postordertraversal(pBST);printf("\n");cleanBST(&pBST);if(!pBST) printf("树已空\n"); return 0;
}
数据结构——二叉搜索树相关推荐
- 数据结构---二叉搜索树
数据结构-二叉搜索树 原理:参考趣学数据结构 代码: 队列代码: #pragma once #define N 100 #define elemType bstTree* #include<st ...
- 二叉搜索树的删除操作可以交换吗_JavaScript数据结构 — 二叉搜索树(BST)ES6实现...
1. 概述 最基本的数据结构是向量和链表,为了将二者的优势结合起来,我们引入了二叉树,可以认为二叉树是列表在维度上的拓展.而今天要介绍的二叉搜索树(BST)则是在形式上借鉴了二叉树,同时也巧妙借鉴了有 ...
- 数据结构 二叉搜索树BST的实现与应用
概念 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 1.若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值 ...
- [学习][数据结构]二叉搜索树
定义 一棵二叉搜索树是以一棵二叉树来组织的,如下图.这样一棵树可以使用一个链表数据结构来表示,其中每个节点就是一个对象.除了key和卫星数据之外,每个节点还包含属性left.right和p,他们分别指 ...
- 数据结构——二叉搜索树的C语言实现
1.什么是二叉搜索树? 2.二叉搜索树的操作 3.二叉搜索树的C语言实现 #include<stdio.h> #include<stdlib.h>#define Element ...
- 数据结构 二叉搜索树的删除
文章目录 概述 待删除的结点没有子树 待删除的结点仅有一颗子树 待删除的结点有两颗子树 C代码实现 概述 这是一篇短文,专门考究一下二叉搜索树的删除. 二叉搜索树的建立非常简单,如果不熟悉的见此文 树 ...
- 23王道数据结构二叉搜索树(BST)算法题(6-11题)总结(伪代码)
6.判断给定的二叉树是否是二叉排序树 算法思想:中序遍历,一棵树为二叉排序树即左右子树为二叉排序树,且当前根节点和左右子树呈递增序列,对左右子树也是如此判断,显然是个递归过程 ...
- 【ACM】二叉搜索树(Binary Search Tree /BS Tree) 小结
动态管理集合的数据结构--二叉搜索树 搜索树是一种可以进行插入,搜索,删除等操作的数据结构,可以用字典或者优先队列. 二叉排序树又称为二叉查找树,他或者为空树,或者是满足如下性质的二叉树. (1)若它 ...
- 【LeetCode笔记】96. 不同的二叉搜索树(Java、动态规划)
文章目录 题目描述 代码 & 思路 精简版 2.0 题目描述 这道题其实不用构造数据结构 二叉搜索树:只要利用这个结构的性质即可,即:左右两子,左小右大 然后用动态规划来做,具体如何推导见思路 ...
最新文章
- cnn卷积中padding作用
- [BZOJ4182]Shopping
- python绘制折线图显示数据_漂亮图表也可用python信手拈来!一文教你学会用Python绘制堆积折线图...
- CSDN 原力计划之最具技术影响力企业博客英雄榜 发布!
- asp.net mvc4使用DropDownList
- 美国飞机安全事件频发:背后黑手竟然是5G?
- K8S 三种探针 readinessProbe、livenessProbe和startupProbe
- 声谱图(spectrogram)、FBank(Mel_spectrogram)和 MFCC(Mel倒谱)到底用哪个作为NN输入?
- CocCocoa Touch框架和Cocoa
- TinyMCE自定义表情包
- 宏源股指期货期权早评:暂未脱离震荡
- 设置hr标签的粗细及颜色
- 关于华为手机P20pro装包时总提示冲突问题
- Banana PI (香蕉派) 安装 ubuntu-core-14 最小核心的操作步骤
- msvcr110.dll系统文件丢失解决方案
- matlab 模拟 峰信号
- iOS基础_C语言第一讲
- JDK源码中,都有哪些设计模式
- 【CSDN博客之星】您的支持就是我最大的动力!喜欢本博客的读者,请拿出您宝贵的几秒钟时间来支持一下吧,非常感谢~
- 三极管放大、开关控制电路测试