C语言实现有序二叉树(1)
在cpp中使用的C语言
头文件
/* 有序二叉树 BsTree */
#ifndef _BT_H
#define _BT_H
/*节点*/
typedef struct BsTreeNode
{
int data;/* 数据 */
struct BsTreeNode* left;/* 左子树 */
struct BsTreeNode* right;/* 右子树 */
}BSTREE_NODE;
/* 二叉树 */
typedef struct BsTree
{
BSTREE_NODE* root;/* 树根 */
size_t size;/* 大小 */
}BSTREE;
/* 初始化为空树 */
void bstree_init(BSTREE* bstree);
/* 释放剩余节点并恢复到初始状态 */
void bstree_deinit(BSTREE* bstree);
/* 插入 */
void bstree_insert(BSTREE* bstree, int data);
/* 删除 */
bool bstree_erase(BSTREE* bstree, int data);
/* 删除所有匹配数据 */
void bstree_remove(BSTREE* bstree, int data);
/* 清空 */
void bstree_clear(BSTREE* bstree);
/* 更新 */
void bstree_update(BSTREE* bstree, int _old, int _new);
/* 判断是否存在 */
bool bstree_exist(BSTREE* bstree, int data);
/* 中序遍历 */
void bstree_travel(BSTREE* bstree);
/* 大小 */
size_t bstree_size(BSTREE* bstree);
/* 高度 */
size_t bstree_height(BSTREE* bstree);
#endif /*_BT_H*/
实现
/* 有序二叉树 */
#include <stdio.h>
#include <stdlib.h>
#include "bt.h" /*********************** 内 部 接 口 ********************************/
/* 创建节点 */
static BSTREE_NODE* create_node(int data)
{
BSTREE_NODE* node = (BSTREE_NODE*)malloc(sizeof(BSTREE_NODE));
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
/* 销毁节点 */
static void destory_node(BSTREE_NODE* node)
{
free(node);
}
/* 将node节点插入到以root为根的子树中 */
static void insert(BSTREE_NODE* node, BSTREE_NODE** root)
{
if ( NULL == *root )
*root = node;
else if (node)
{
if ( node->data < (*root)->data )
insert(node, &((*root)->left));
else
insert(node, &((*root)->right));
}
}
/* 返回以参数root为根的子树中,数据与参数data匹配的节点的父节点中
* 指向该节点的指针型成员变量的地址
* 目的是在删除节点后,要将删除节点的子节点接到此变量的地址上。
*/
static BSTREE_NODE** find(int data, BSTREE_NODE** root)
{
if (NULL == *root)
return root;
if (data < (*root)->data)
return find(data, &(*root)->left);
if (data > (*root)->data)
return find(data, &(*root)->right);
return root;
}
/* 删除以参数root为根的子树 */
static void clear(BSTREE_NODE** root)
{
if (*root)
{
clear(&(*root)->left);
clear(&(*root)->right);
destory_node(*root);
*root = NULL;
}
}
/* 中序遍历以参数root为根的子树 */
static void travel(BSTREE_NODE* root)
{
if (root)
{
travel(root->left);
printf("%d ", root->data);
travel(root->right);
}
}
/* 返回以参数root为根的子树的高度 */
static size_t height(BSTREE_NODE* root)
{
if (root)
{
size_t lh = height(root->left);
size_t rh = height(root->right);
return (((lh > rh) ? lh : rh) + );
}
return ;
}
/*********************** 外 部 接 口 ********************************/
/* 初始化为空树 */
void bstree_init(BSTREE* bstree)
{
bstree->root = NULL;
bstree->size = ;
}
/* 释放剩余节点并恢复到初始状态 */
void bstree_deinit(BSTREE* bstree)
{
clear(&bstree->root);
bstree->size = ;
}
/* 插入 */
void bstree_insert(BSTREE* bstree, int data)
{
insert(create_node(data), &bstree->root);
++bstree->size;
}
/* 删除 */
bool bstree_erase(BSTREE* bstree, int data)
{
BSTREE_NODE** node = find(data, &bstree->root);
if (*node)
{
/* 将匹配节点的左子树插入其右子树 */
insert((*node)->left, &(*node)->right);
BSTREE_NODE* tmp = *node;
/* 用匹配节点的右子树的根节点取代匹配节点 */
*node = (*node)->right;
/* 销毁匹配节点 */
destory_node(tmp);
--bstree->size;
return true;
}
return false;
}
/* 删除所有匹配数据 */
void bstree_remove(BSTREE* bstree, int data)
{
while(bstree_erase(bstree, data));
}
/* 清空 */
void bstree_clear(BSTREE* bstree)
{
bstree_deinit(bstree);
}
/* 更新 */
void bstree_update(BSTREE* bstree, int _old, int _new)
{
while(bstree_erase(bstree, _old))
bstree_insert(bstree, _new);
}
/* 判断是否存在 */
bool bstree_exist(BSTREE* bstree, int data)
{
return *find(data, &bstree->root) != NULL;
}
/* 中序遍历 */
void bstree_travel(BSTREE* bstree)
{
travel(bstree->root);
printf("\n");
}
/* 大小 */
size_t bstree_size(BSTREE* bstree)
{
return bstree->size;
}
/* 高度 */
size_t bstree_height(BSTREE* bstree)
{
return height(bstree->root);
}
测试用例
/* 有序二叉树 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "bt.h" int main ()
{
srand((unsigned)time(NULL));
BSTREE bstree;
bstree_init(&bstree);
int i;
for (i = ; i < ; ++i)
bstree_insert(&bstree, rand()%); bstree_travel(&bstree);
bstree_clear(&bstree);
bstree_insert(&bstree, );
bstree_insert(&bstree, );
bstree_insert(&bstree, );
bstree_insert(&bstree, );
bstree_insert(&bstree, );
bstree_insert(&bstree, );
bstree_insert(&bstree, );
bstree_insert(&bstree, );
bstree_insert(&bstree, );
bstree_travel(&bstree);
printf("大小:%u\n树高:%u\n",
bstree_size(&bstree), bstree_height(&bstree)); bstree_erase(&bstree, );
bstree_travel(&bstree);
bstree_insert(&bstree, );
bstree_insert(&bstree, );
bstree_travel(&bstree);
bstree_update(&bstree, , );
bstree_travel(&bstree);
bstree_remove(&bstree, );
bstree_travel(&bstree);
if (bstree_exist(&bstree, /**/))
printf("有!\n");
else
printf("没有!\n"); bstree_deinit(&bstree);
system("pause");
return ;
}
练习:(一般的二叉树)
已知某二叉树前序遍历的结果为:1 2 4 7 3 5 6 8
中序遍历的结果为:4 7 2 1 5 3 8 6
编写三个函数分别用于重建二叉树、前序遍历和中序遍历。
C语言实现有序二叉树(1)的更多相关文章
- c++ 有序二叉树的应用
实作:以有序二叉树记录学生签到时间及名字,然后以名字升序输出学生签到信息 stricmp,strcmpi 原型:extern int stricmp(char *s1,char * s2); 用法:# ...
- C语言数据结构之二叉树的实现
本篇博文是博主在学习C语言算法与数据结构的一些应用代码实例,给出了以二叉链表的形式实现二叉树的相关操作.如创建,遍历(先序,中序后序遍历),求树的深度,树的叶子节点数,左右兄弟,父节点. 代码清单如下 ...
- 数据结构(C语言版)---二叉树
1.二叉树:任意一个结点的子结点个数最多两个,且子结点的位置不可更改,二叉树的子树有左右之分. 1)分类:(1)一般二叉树(2)满二叉树:在不增加树的层数的前提下,无法再多添加一个结点的二叉树就是满二 ...
- c语言编程之二叉树
利用链表建立二叉树,完成前序遍历.中序遍历.后序遍历. 建立二叉树用的是前序遍历建立二叉树: #include<stdio.h> #include<stdlib.h> #inc ...
- C语言递归实现二叉树(二叉链表)的三种遍历和销毁操作(实验)
今天写的是二叉树操作的实验,这个实验有三个部分: ①建立二叉树,采用二叉链表结构 ②先序.中序.后续遍历二叉树,输出节点值 ③销毁二叉树 二叉树的节点结构定义 typedef struct BiTNo ...
- 数据结构之---C语言实现线索二叉树
//线索二叉树,这里在二叉树的基础上增加了线索化 //杨鑫 #include <stdio.h> #include <stdlib.h> typedef char ElemTy ...
- c语言描述的二叉树的基本操作(层序遍历,递归,非递归遍历)
#include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define ...
- Leecode刷题之旅-C语言/python-101对称二叉树
/* * @lc app=leetcode.cn id=101 lang=c * * [101] 对称二叉树 * * https://leetcode-cn.com/problems/symmetri ...
- C语言递归实现二叉树的先序、中序、后序遍历
#include <stdio.h> #include <stdlib.h> //*****二叉树的二叉链表存储表示*****// typedef struct BiNode ...
随机推荐
- C# - DES加密+解密
#region ===========================DES算法=================================== private static string ke ...
- 滚动栏范围位置函数(SetScrollRange、SetScrollPos、GetScrollRange、GetScrollPos)
滚动栏的范围是一对整数,默认情况下,滚动栏的范围是0~100. SetScrollRange(hwnd,iBar,iMin,iMax,bRedraw)这里的iBar參数要么是SB_VERT,要么是SB ...
- 源码推荐(7.17):不规则按钮类似于遥控器按钮,一个可以最大程度简化PageView与TabView切换的第三方框架
不规则按钮,类似于遥控器按钮,可以单独控制按钮的上下左右(作者:masa_chu) 不规则按钮,类似于遥控器按钮,可以单独控制按钮的上下左右 测试环境:Xcode 6.2,iOS 6.0以上 Lazy ...
- javascript设计模式——Module
Module模式是提供公有和私有方法的代码块,有利于封装组织代码,可减少变量及函数名与其它模块的冲突. 推荐阅读: http://www.adequatelygood.com/JavaScript-M ...
- JavaScript input type=file 获取文件大小及类型限制
<input name="txtName" type="file" id="pic" onchange="loadImage ...
- QT-Creator C/C++ 打地鼠小游戏
废话少说先上图: 这个游戏纯属土鳖思路,没有用到什么游戏引擎. 1.使用按钮或QLabel铺满窗口. 2.通过简单算法随机动态的设置按钮矩阵中某个按钮的背景图像. 3.同步2过程反复设置多个按钮背景实 ...
- android stuido 快捷键
Alt+回车 导入包,自动修正 Ctrl+N 查找类 Ctrl+Shift+N 查找文件 Ctrl+Alt+L 格式化代码 Ctrl+Alt+O 优化导入的类和包 Alt+Insert 生成代码 ...
- BF算法(朴素的模式匹配算法)
#include <stdio.h> #include <stdlib.h> int Index_BF(char S[],char T[])//s为目标串(长串),t为模式串( ...
- python正则表达式练习篇
练习一: 利用who命令输出所有已经登录系统的用户的信息,并把登录名.用户登录时的电传.登录时间.登录地址利用正则表达式分割开来. 数据的格式: %who wesc console Jun 20 20 ...
- mysql学习(十)多表查询
多表查询时,要给表名起别名,给字段名其别名(当两个表含有重复字段时) select p.name, c.name, pid from products p, cats c;//得到的结果为笛卡尔乘积 ...