C语言之二叉树
规定:根节点的值大于左节点但小于右节点的值,所以二叉树的值插入是唯一的,最后形成的树只跟根节点有关
定义节点:
struct tree_node {
TypeElem elem;
struct tree_node *fa;
struct tree_node *left;
struct tree_node *right;
};
#include <stdio.h>
#include <stdlib.h> typedef int TypeElem; struct tree_node {
TypeElem elem;
struct tree_node *fa;
struct tree_node *left;
struct tree_node *right;
}; struct tree_node *root_ptr; //指向根节点的指针 #define IS_ROOT_NODE(ptree_fa, ptree, x) do{ if(ptree_fa) { \
if (ptree == ptree_fa->left) \
ptree_fa->left = x; \
else if (ptree == ptree_fa->right) \
ptree_fa->right = x; \
}else \
root_ptr = x; }while () //如果删除的是根节点root_ptr就变了 /* 在父节点下插入子节点(有可能是孙子节点了) */
struct tree_node *Insert(TypeElem elem, struct tree_node *T_fa, struct tree_node *T)
{
if (T == NULL) {
T = (struct tree_node *)malloc(sizeof(struct tree_node));
if (!T) {
printf("malloc error\n");
return NULL;
}
T->fa = T_fa;
T->elem = elem;
T->left = T->right = NULL;
}
else if (elem < T->elem)
T->left = Insert(elem, T, T->left);
else if (elem > T->elem)
T->right = Insert(elem, T, T->right); return T;
} struct tree_node *find_val(struct tree_node *rootp, TypeElem elem)
{
if (!rootp) {
printf("don't find\n");
return NULL;
}
//遍历:前序、中序、后序
if (rootp->elem == elem)
return rootp;
else if (rootp->elem > elem) {
return find_val(rootp->left, elem); //递归
}
else if (rootp->elem < elem) {
return find_val(rootp->right, elem); //递归
}
return NULL;
} struct tree_node *find_min_val(struct tree_node *rootp)
{
while (rootp->left) {
rootp = rootp->left;
}
return rootp;
} struct tree_node *find_max_val(struct tree_node *rootp)
{
while (rootp->right) {
rootp = rootp->right;
}
return rootp;
} int delete_tree(TypeElem elem, int isfree)
{
struct tree_node *ptree = find_val(root_ptr, elem);
struct tree_node *ptree_fa = ptree->fa;
struct tree_node *min_tree; if (!ptree)
return -;
if (!(ptree->left) && !(ptree->right)) {
IS_ROOT_NODE(ptree_fa, ptree, NULL);
}
else if (!(ptree->left) && ptree->right) {
IS_ROOT_NODE(ptree_fa, ptree, ptree->right);
ptree->right->fa = ptree_fa;
}
else if (ptree->left && !(ptree->right)) {
IS_ROOT_NODE(ptree_fa, ptree, ptree->left);
ptree->left->fa = ptree_fa;
}
else if (ptree->left && ptree->right) {
min_tree = find_min_val(ptree->right);
delete_tree(min_tree->elem, ); //递归
IS_ROOT_NODE(ptree_fa, ptree, min_tree);
min_tree->left = ptree->left;
min_tree->right = ptree->right;
min_tree->fa = ptree->fa;
}
if (isfree)
free(ptree);
return ;
} int main()
{
int i;
root_ptr = Insert(, NULL, root_ptr); //得到指向根节点的指针
TypeElem a[] = { ,,,,,,,, }; //依次插入9个节点
for (i = ; i < ; i++)
Insert(a[i], root_ptr->fa, root_ptr);
if (!delete_tree(, ))
printf("delete_tree ok\n");
if (root_ptr) {
if (find_val(root_ptr, ))
printf("find node\n");
}
return ;
}
形成的树结构:

如果删除根节点6,依然能找到节点9
C语言之二叉树的更多相关文章
- C语言实现二叉树-02版
---恢复内容开始--- 昨天,提交完我们的二叉树项目后,今天早上项目经理早早给我打电话: 他说,小伙子干的不错.但是为什么你上面的insert是recusive的呢? 你难道不知道万一数据量大啦!那 ...
- C语言实现二叉树-利用二叉树统计单词数目
昨天刚参加了腾讯2015年在线模拟考: 四道大题的第一题就是单词统计程序的设计思想: 为了记住这一天,我打算今天通过代码实现一下: 我将用到的核心数据结构是二叉树: (要是想了解简单二叉树的实现,可以 ...
- C语言实现二叉树
二叉树的重要性就不用多说啦: 我以前也学习过,但是一直没有总结: 网上找到的例子,要么是理论一大堆,然后是伪代码实现: 要么是复杂的代码,没有什么解释: 最终,还是靠FQ找到一些好的文章,参考地址我会 ...
- C语言实现二叉树的基本操作
二叉树是一种非常重要的数据结构.本文总结了二叉树的常见操作:二叉树的构建,查找,删除,二叉树的遍历(包括前序遍历.中序遍历.后序遍历.层次遍历),二叉搜索树的构造等. 1. 二叉树的构建 二叉树的基本 ...
- C语言描述二叉树的实现及操作(链表实现)
概述 二叉树为每个节点最多有两个儿子节点(左儿子节点和右儿子节点)的树. 前序遍历:根结点 ---> 左子树 ---> 右子树. 中序遍历:左子树---> 根结点 ---&g ...
- C语言数据库-二叉树
一.定义 二叉树在图论中是这样定义的:二叉树是一个连通的无环图,并且每一个顶点的度不大于3.有根二叉树还要满足根结点的度不大于2.有了根结点之后,每个顶点定义了唯一的父结点,和最多2个子结点.然而,没 ...
- go语言浅析二叉树
Hello,各位小伙伴大家好,我是小栈君,今天给大家带来的分享是关于关于二叉树相关的知识点,并用go语言实现一个二叉树和对二叉树进行遍历. 我们主要针对二叉树的概念,go实战实现二叉树的前序遍历.中序 ...
- c语言_二叉树的建立以及3种递归
二叉树c语言的实现 二叉树的建立 二叉树的数据结构 typedef struct node{ int data; struct node* left; struct node* ri ...
- C语言实现二叉树-04版
二叉树,通常应当是研究其他一些复杂的数据结构的基础.因此,通常我们应该精通它,而不是了解:当然,可能并不是每个人都认同这种观点,甚至有些人认为理解数据结构就行了!根本没有必要去研究如何实现,因为大多数 ...
- C语言实现二叉树-03版
我们亲爱的项目经理真是有创意,他说你给我写得二叉树挺好的: 功能还算可以:插入节点,能够删除节点: 可是有时候我们只是需要查找树的某个节点是否存在: 所以我希望你能够给我一个find功能: 还有就是, ...
随机推荐
- Linux 虚拟机的计划维护
Azure 定期执行更新,以提高虚拟机的主机基础结构的可靠性.性能及安全性. 此类更新包括修补宿主环境(例如操作系统.虚拟机监控程序以及主机上部署的各种代理)中的软件组件.升级网络组件以及硬件解除授权 ...
- C#中的多线程 - 同步基础 z
原文:http://www.albahari.com/threading/part2.aspx 专题:C#中的多线程 1同步概要Permalink 在第 1 部分:基础知识中,我们描述了如何在线程上启 ...
- ubuntu 16.04 virtualbox could not insert 'vboxdrv': Required key not available 问题解决方法
从 内核版本 4.4.0-20 开始,在开启了 Secure Boot 的电脑上,未注册的 kernel 模块不再允许执行,所以如果想在保持 Secure Boot 的情况下依然允许执行,我们需要做的 ...
- Spark资源调度分配内幕天机彻底解密:Driver在Cluster模式下的启动、两种不同的资源调度方式源码彻底解析、资源调度内幕总结
本课主题 Master 资源调度的源码鉴赏 资源调度管理 任务调度与资源是通过 DAGScheduler.TaskScheduler.SchedulerBackend 等进行的作业调度 资源调度是指应 ...
- Timer类注意事项
Java的一个Timer对象可以执行多个Timertask任务,但是一个Timer对象本身只有一个线程,如果向他提交多个task,并且某个task相当耗时的话,其他的task即使到了执行时间,仍然会等 ...
- ES6-模块导入导出
基本用法 命名导出(named exports) 可以直接在任何变量或者函数前面加上一个 export 关键字,就可以将它导出. 例如: export const sqrt = Math.sqrt; ...
- POJ-2429 GCD & LCM Inverse---给出gcd和lcm求原来两个数
题目链接: https://cn.vjudge.net/problem/POJ-2429 题目大意: 给出两个数的gcd和lcm,求原来的这两个数(限定两数之和最小). 解题思路: 首先,知道gcd和 ...
- Intellij IDEA 代码中类非全路径显示
- 关于notify() 和notifyAll() 一个需要注意的地方
notify() 和 notifyAll()都是唤醒其他正在等待同一个对象锁的线程. 下面是我遇到的一个问题,记下来,免得忘了. 直接上代码,有错误的代码: 代码描述:有一个Caculate类,类中又 ...
- 解决 git pull 报错 fatal: refusing to merge unrelated histories
我在Github新建一个仓库,写了License,然后把本地一个写了很久仓库上传. 先pull,因为两个仓库不同,发现refusing to merge unrelated histories,无法p ...