第五篇、C_二叉搜索树
1.二叉树的查找功能的时间复杂度比链表的好
2.删除节点的稍微复杂点
>没有节点,直接删除
>只有左节点(或者右节点),直接用该节点的左节点(或者右节点)替代要删除的节点
>有左节点并且有右节点,用左节点替代
3.二叉树的遍历方式:
/*
1.中序遍历的递归算法定义: 若二叉树非空,则依次执行如下操作: ⑴遍历左子树; ⑵访问根结点; ⑶遍历右子树。[3] 2.先序遍历的递归算法定义: 若二叉树非空,则依次执行如下操作: ⑴ 访问根结点; ⑵ 遍历左子树; ⑶ 遍历右子树。 3.后序遍历得递归算法定义: 若二叉树非空,则依次执行如下操作: ⑴遍历左子树; ⑵遍历右子树; ⑶访问根结点
*/
typedef struct node{
int num;
struct node *left;
struct node *right;
}Node;
typedef struct {
Node *root;
}Tree;
/**
*@brief 建树
*/
Tree *createTree()
{
Tree *tree = malloc(sizeof(Tree));
tree -> root = NULL;
return tree;
}
/**
*@brief 建树的节点
*/
Node *createNode(int num)
{
Node *node = malloc(sizeof(Node));
node -> num = num;
node -> left = NULL;
node -> right = NULL;
return node;
}
/**
*@brief 非递归插入
*/
void insert(Tree *tree,int n)
{
if(tree -> root == NULL){
tree -> root = createNode(n);
}else{
Node *p = tree -> root;
Node *parent = NULL;
while(p != NULL)
{
parent = p; // 记录当前移动的位置
if(p -> num < n)
{
p = p -> left;
}
else if(p -> num > n)
{
p = p -> right;
}
else{ // 相等就不再插入
return;
}
}
// 找到位置后插入
if (n < parent -> num)
{
parent -> left = createNode(n);
}else{
parent -> right = createNode(n);
}
}
}
/**
*@brief 递归插入
*/
void insert(Node *node,int n)
{
if(node == NULL){
node = createNode(n);
}
else if(n < node-> num){
node -> left = insert(node -> left, n);
}
else{
node -> right = insert(node -> right, n);
}
}
/**
*@brief 查找
*/
Node *search(Tree tree,int n)
{
Node *p = tree -> root;
while(p != NULL)
{
if(n < p -> num)
{
p = p -> left;
}
else if (n > p -> num)
{
p = p -> right;
}
else {
return p;
}
}
return NULL;
}
/*
1.中序遍历的递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴遍历左子树;
⑵访问根结点;
⑶遍历右子树。[3]
2.先序遍历的递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴ 访问根结点;
⑵ 遍历左子树;
⑶ 遍历右子树。
3.后序遍历得递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴遍历左子树;
⑵遍历右子树;
⑶访问根结点
*/
/**
*@brief 先序遍历
*@param node tree->root
*/
void preOrder(Node *node)
{
if (node != NULL)
{
printf("%d",node -> num);
preOrder(node -> left);
preOrder(node -> right);
}
}
/**
*@brief 中序遍历
*/
void inOrder(Node *node)
{
if (node != NULL)
{
inOrder(node -> left);
printf("%d",node -> num);
inOrder(node -> right);
}
}
/**
*@brief 后序遍历
*/
void tailOrder(Node *node)
{
if (node != NULL)
{
tailOrder(node -> left);
tailOrder(node -> right);
printf("%d",node -> num);
}
}
/**
*@brief 删除节点
1//只有左节点,则左节点代替他的位置
2//只有右节点,则右节点代替他的位置
3//既有左节点又有右节点,则左子树的最右节点代替原节点
*/
bool deleteNode(Node *node,int n)
{
Node *p = node;
Node *q;
int temp;
while(p != NULL && n != p -> num)
{
q = p;
if(p -> num < n)
{
p = p -> left;
}
else if(p -> num > n)
{
p = p -> right;
}
else{ // 相等就不再插入
}
}
if(p == NULL){
printf("没有此元素");
}
else{ // 如果找到要删除的节点
// 1.如果找到的节点,没有左子树和右子树
if(p -> left == NULL && P -> right == NULL)
{
if(p == q -> left)
{
q -> left = NULL;
}
if(p == q -> right)
{
q -> right = NULL;
}
free(p);
p == NULL;
}
// 2.找到节点,但是要删除的节点只有左子树或者右子树
// 2.1 只有左子树
else if (NULL == p -> right && NULL != p -> left)
{
if(p == q ->left)
{
q -> left = p -> left;
}else if(p == q -> right)
{
q ->right = p -> left;
}
free(p);
p = NULL;
}
// 2.2 只有右子树
else if (NULL != p -> right && NULL == p -> left)
{
if(p == q ->left)
{
q -> left = p -> right;
}else if(p == q ->right)
{
q ->right = p -> right;
}
free(p);
p = NULL;
}
// 3.如果查找到的节点,左右子树都有(本代码使用直接前驱,也可以使用直接后继)
else if (NULL != P -> right && NULL != p -> left)
{
Node *s,sParent;
sParent = p;
s = sParent -> left;
while (NULL != s -> right) // 找到p的直接前驱
{
sParent = s;
s = s -> right;
}
temp = s -> num;
deleteNode(node,temp); // 递归
p -> num = temp;
}
}
}
第五篇、C_二叉搜索树的更多相关文章
- 剑指Offer的学习笔记(C#篇)-- 二叉搜索树的后序遍历序列
题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 一 . 解题思想与二叉搜索树概念 (1). 二叉树 ...
- leecode第二百三十五题(二叉搜索树的最近公共祖先)
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...
- 数据结构-二叉树(应用篇)-之二叉搜索树 C和C++的实现
一.概念 二叉搜索树(Binary Sort Tree/Binary Search Tree...),是二叉树的一种特殊扩展.也是一种动态查找表. 在二叉搜索树中,左子树上所有节点的均小于根节点,右子 ...
- LeetCode刷题191130 --基础知识篇 二叉搜索树
休息了两天,状态恢复了一下,补充点基础知识. 二叉搜索树 搜索树数据结构支持许多动态集合操作,包括Search,minimum,maximum,predecessor(前驱),successor(后继 ...
- 《剑指offer》第五十四题(二叉搜索树的第k个结点)
// 面试题54:二叉搜索树的第k个结点 // 题目:给定一棵二叉搜索树,请找出其中的第k大的结点. #include <iostream> #include "BinaryTr ...
- 【数据结构05】红-黑树基础----二叉搜索树(Binary Search Tree)
目录 1.二分法引言 2.二叉搜索树定义 3.二叉搜索树的CRUD 4.二叉搜索树的两种极端情况 5.二叉搜索树总结 前言 在[算法04]树与二叉树中,已经介绍过了关于树的一些基本概念以及二叉树的前中 ...
- Binary Search-使用二叉搜索树
终于到二叉树了,每次面试时最担心面试官问题这块的算法问题,所以接下来就要好好攻克它~ 关于二叉树的定义网上一大堆,这篇做为二叉树的开端,先了解一下基本概念,直接从网上抄袭: 先了解下树的概念,bala ...
- LeetCode.938-范围内求二叉搜索树节点值之和(Range Sum of BST)
这是悦乐书的第359次更新,第386篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第221题(顺位题号是938).给定二叉搜索树的根节点,返回节点值在[L,R]之间的所有 ...
- 数据结构学习笔记_树(二叉搜索树,B-树,B+树,B*树)
一.查找二叉树(二叉搜索树BST) 1.查找二叉树的性质 1).所有非叶子结点至多拥有两个儿子(Left和Right): 2).所有结点存储一个关键字: 3).非叶子结点的左指针指向小于其关键字的子树 ...
随机推荐
- hdoj 2111 Saving HDU
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- jQuery each的实现与call方法的详细介绍
转载原出处: http://www.f2es.com/jquery-each-intro/ 先贴上jquery实现each功能的源代码(把常用的call部分提取出来,为了方便理解,就进行了一定的修改) ...
- CSS链接、光标、DHTML、缩放
个属性 18.2 CSS中光标的使用(更详细可看文档) 属性名称 属性值 说明 cursor auto ...
- iOS 9 学习系列:UIStack View (转载)
作者:Nathan_Bao 地址:http://www.jianshu.com/p/1991e6c2881a 在 iOS9 中,Apple 引入了 UIStackView,他让你的应用可以通过简单的方 ...
- ThinkPHP Volist标签
Volist标签主要用于在模板中循环输出数据集或者多维数组. volist标签(循环输出数据) 闭合 非闭合标签 属性 name(必须):要输出的数据模板变量 id(必须):循环变量 offset(可 ...
- nginx+tomcat动静分离的核心配置
#所有jsp的页面均交由tomcat或resin处理 location ~ .(jsp|jspx|do)?$ { proxy_set_header Host $host; proxy_set_head ...
- 已超过了锁请求超时时段。 (Microsoft SQL Server,错误: 1222)
操作SQLServer数据库时.遇到这种问题:已超过了锁请求超时时段. (Microsoft SQL Server,错误: 1222) 经过查找材料了解为资源抢占,照成死锁,杀死进程就OK了.详细操作 ...
- eoe推荐的优秀博客
<a href="http://my.eoe.cn/huodong/archive/5430.html">http://my.eoe.cn/huodong/archiv ...
- 第十一章 Function类型
在ECMAScript中,Function(函数)类型实际上是对象.每个函数也是Function类型的实例,而且都与其它引用类型一样具有属性和方法.由于是函数对象,因此函数名实际上也是一个指向函数对象 ...
- 实例源码--Android智能家居系统源码
下载源码 技术要点: 1.Android应 用开发基础框架 2.SQLITE数据库的 使用 3.网络通信 4.GOOGLE地图模块 5.源码带有非常详 细的中文注释 ...... 详细介绍: ...