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_二叉搜索树的更多相关文章

  1. 剑指Offer的学习笔记(C#篇)-- 二叉搜索树的后序遍历序列

    题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 一 . 解题思想与二叉搜索树概念 (1). 二叉树 ...

  2. leecode第二百三十五题(二叉搜索树的最近公共祖先)

    /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...

  3. 数据结构-二叉树(应用篇)-之二叉搜索树 C和C++的实现

    一.概念 二叉搜索树(Binary Sort Tree/Binary Search Tree...),是二叉树的一种特殊扩展.也是一种动态查找表. 在二叉搜索树中,左子树上所有节点的均小于根节点,右子 ...

  4. LeetCode刷题191130 --基础知识篇 二叉搜索树

    休息了两天,状态恢复了一下,补充点基础知识. 二叉搜索树 搜索树数据结构支持许多动态集合操作,包括Search,minimum,maximum,predecessor(前驱),successor(后继 ...

  5. 《剑指offer》第五十四题(二叉搜索树的第k个结点)

    // 面试题54:二叉搜索树的第k个结点 // 题目:给定一棵二叉搜索树,请找出其中的第k大的结点. #include <iostream> #include "BinaryTr ...

  6. 【数据结构05】红-黑树基础----二叉搜索树(Binary Search Tree)

    目录 1.二分法引言 2.二叉搜索树定义 3.二叉搜索树的CRUD 4.二叉搜索树的两种极端情况 5.二叉搜索树总结 前言 在[算法04]树与二叉树中,已经介绍过了关于树的一些基本概念以及二叉树的前中 ...

  7. Binary Search-使用二叉搜索树

    终于到二叉树了,每次面试时最担心面试官问题这块的算法问题,所以接下来就要好好攻克它~ 关于二叉树的定义网上一大堆,这篇做为二叉树的开端,先了解一下基本概念,直接从网上抄袭: 先了解下树的概念,bala ...

  8. LeetCode.938-范围内求二叉搜索树节点值之和(Range Sum of BST)

    这是悦乐书的第359次更新,第386篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第221题(顺位题号是938).给定二叉搜索树的根节点,返回节点值在[L,R]之间的所有 ...

  9. 数据结构学习笔记_树(二叉搜索树,B-树,B+树,B*树)

    一.查找二叉树(二叉搜索树BST) 1.查找二叉树的性质 1).所有非叶子结点至多拥有两个儿子(Left和Right): 2).所有结点存储一个关键字: 3).非叶子结点的左指针指向小于其关键字的子树 ...

随机推荐

  1. Swift 基本语法1

    一.Swift简介 2010年的夏天,苹果公司的开发人员Chris Lattne接到了一个特别的任务,为OS X 和iOS平台开发下一代的编程语言,也就是Swift. 苹果公司于2014年WWDC(苹 ...

  2. CentOS6.2下安装eclipse

    在eclipse官网下载eclipse的linux版本(此处省略下载过程),我下载的是eclipse-jee-indigo-SR2-linux-gtk.tar.gz,下面是安装过程:  1.sudo ...

  3. web项目设计中框架的数据流

    这张图虽然简单,但是很好的说明了一个web框架,需要实现那些模块. 图片来自 <Go Web编程>

  4. 最全面的Android Intent机制讲解

    对于大型软件开发经验较少的程序员来说,这可能是一个不太容易理解的抽象概念,因为它与我们平常使用的简单函数调用,或者通过库调用接口的方式不太一样.在 Intent 的使用中你看不到直接的函数调用,相对函 ...

  5. Behavioral模式State模式

    1.意向 同意一个目标,然后改变其内部状态,改变它的行为. 对象似乎改变它的类别. 2.别名 状态对象(Objects for States) 3.动机 考虑一个表示网络连接的类TCPConnecti ...

  6. [Effective C++ --026]尽可能延后变量定义式的出现时间

    引言 每一次构造和析构都需要成本,因此我们在设计代码的时候,应该尽可能考虑到构造和析构的成本. 第一节 延后实现 考虑有以下的代码: void encrypt(string& s); stri ...

  7. [Effective C++ --012]复制对象时勿忘其每一个成分

    引言: 在深拷贝和浅拷贝的理解中,我们知道了“拷贝构造函数”一词,并且也了解了它的构成. A(const A& r); // 形式有多种,在这里只列出一个 因此,在值传递的应用场景里,我们可以 ...

  8. IT软件开发 书籍汇总

    数据库: MYSQL ->  Effective MySQL 之 SQL 语句最优化   [美] Ronald Bradford 著 李雪锋 译 清华大学出版社 开发书籍 PHP核心技术与最佳实 ...

  9. CreateToolhelp32Snapshot

    CreateToolhelp32Snapshot CreateToolhelp32Snapshot函数为指定的进程.进程使用的堆[HEAP].模块[MODULE].线程[THREAD])建立一个快照[ ...

  10. Android View的绘制机制流程深入详解(二)

    本系列文章主要着重深入介绍Android View的绘制机制及流程,第二篇主要介绍并分析Android视图的绘制的原理和流程.主要从 onMeasure().onLayout()和onDraw()这三 ...