第五篇、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).非叶子结点的左指针指向小于其关键字的子树 ...
随机推荐
- 转载ASP.NET 状态管理Application,Session,Cookie和ViewState用法
转载原地址 http://www.cnblogs.com/cuishao1985/archive/2009/09/24/1573403.html ASP.NET状态管理 APPlication,Ses ...
- 经验之巧妙的应用Map
后台: @RequestMapping("/cmci/v_divide_check_add.do") public String toDivideCheckAdd(HttpS ...
- Gitbook安装
Gitbook安装 Gitbook是从NMP安装的,命令行: $ npm install gitbook -g 安装完之后,你可以检验下是否安装成功: $ gitbook -V 0.4.2 如果你看到 ...
- 安卓Android控件ListView获取item中EditText值
可以明确,现在没有直接方法可以获得ListView中每一行EditText的值. 解决方案:重写BaseAdapter,然后自行获取ListView中每行输入的EditText值. 大概算法:重写Ba ...
- yarn 集群部署,遇到的问题小结
版本号信息: hadoop 2.3.0 hive 0.11.0 1. Application Master 无法訪问 点击application mater 链接,出现 http 500 错 ...
- 主流数据库字段类型转.Net类型的方法
最近在阅读一些开源的代码,发现其中有些方法总结的很全面,至少在我做同样的事情时候,需要抓破脑袋想活着google,现在看到了这个关于主流数据库字段类型转.Net类型的方法,故收藏之,也顺便分享给那些能 ...
- memcpy内存拷贝及优化策略图解
一般内存拷贝与优化 代码实现 #include<iostream> usingnamespace std; //不安全的内存拷贝(当源内存地址与目标内存地址重叠时会产生错误) void h ...
- 根据Android架构分层推荐开发书籍
Android系统的架构可以分为六个部分.笔者根据自己的体会为大家推荐每个部分对应的精品书籍,不喜勿喷. 1.Android Application <Android Developer Do ...
- SAP进销存难点分析及对策
1.基本需求: 业务部门提出如上表格式进销存需求,并且金额要和总账中存货科目保持一致,如果要实现上表格式进校存,可以通过SAP标准程序(MC.9.MB51.MB5B)加工繁琐而成.现分析一下SAP标准 ...
- C 双向链表
单链表的结点都只有一个指向下一个结点的指针 单链表的数据元素无法直接访问其前驱元素 逆序访问单链表中的元素是极其耗时的操作! len = LinkList_Length(list); for (i=l ...