c语言数据结构 树的基本操作
树的基本操作有创建,插入,删除,以及各种遍历的应用,如:利用后序遍历求高度,利用前序遍历求层数的结点
基本算法思路:创建二叉树函数参数必须接受二级指针!如果使用同级指针,无法返回创建后的结果,利用递归malloc函数完成创建
插入(检索树):根据检索树特性,在插入必须判断根节点左右两边的值来完成插入
删除:如果删除的是节点是叶结点,直接free。如果有一个子树,将其父节点指向删除节点的儿子。如果两个子树,遍历右节点找到最大的data,将他的data复制给删除data,然后删除该节(重复第一二种情况)
更多应用举例请看代码(普通二叉树,检索树)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<conio.h>
struct tree1 {
char data;//数据域
struct tree1* light;//指向左孩子的指针
struct tree1* right;//指向右孩子的指针
};
char ch;
struct tree1* root;
struct tree1 *del_node1= NULL;//需要删除的节点
void create(struct tree1** p);//创造而叉树
void create_tree();//创造检索树
void front(struct tree1* p);//前序遍历
void midder(struct tree1* p);//中序遍历
void post(struct tree1* p);//后序遍历
void toot(struct tree1* p);//以括号的形式输出二叉树
//int h(struct tree1* p);//求该节点的高度
struct tree1* enter_node(char a, struct tree1** p);//插入检索树的节点
struct tree1* find_father(struct tree1* p);//返回父节点的指针,若无寻找不到则返回空指针,函数不接受根节点!
struct tree* find_rmax(struct tree1* p);//寻找右节点中的最大值
int find_layer(struct tree1* p,char a,int n);//寻找树中指定内容 并返回层数
int find_node(struct tree1* p, char a);//如果有结点返回1,没有返回0
int layer = 0;//接收节点层数
void main()
{
root = NULL;
printf("输入#代表此节点为终端结点\n");
create(&root);
front(root);
printf("\n");
midder(root);
printf("\n");
post(root);
printf("\n");
toot(root);
printf("\n"); printf("%d\n", find_layer(root, 'H', 1)); }
void create(struct tree1** p)
{ std::cin >> ch;
if (ch == '#')
{
*p = NULL;
return;
}
else
{
*p = (struct tree1*)malloc(sizeof(struct tree1));
(*p)->data = ch;
create(&((*p)->light));
create(&((*p)->right));
}
}
void front(struct tree1* p)
{
if (p != NULL)
{
printf("%c", p->data);
front(p->light);
front(p->right);
}
}
void midder(struct tree1* p)
{
if (p != NULL)
{
midder(p->light);
printf("%c", p->data);
midder(p->right);
}
}
void post(struct tree1* p)
{
if (p != NULL)
{
post(p->light);
post(p->right);
printf("%c", p->data);
}
}
void toot(struct tree1* p)
{
if (p == NULL)
{
printf("0");
return;
} printf("%c", p->data);
if (p->light == NULL && p->right == NULL)
{
return;
}
printf("(");
toot(p->light);
printf(",");
toot(p->right);
printf(")"); }
void create_tree()
{
struct tree1* p=NULL;
int hj = 0;
char c;
root = (struct tree1*)malloc(sizeof(struct tree1));
//自己赋值根节点的数据域
std::cin >> c;
root->data = c;
root->light = NULL;
root->right = NULL;
//以#结束创建
while (1)
{
std::cin >> c;
if (c == '#')
break;
if (hj == 0)
{
hj++;
p=enter_node(c, &(root));
}
else
{
p= enter_node(c, &p);
}
}
}
struct tree1* enter_node(char a,struct tree1 **p)
{
if (*p == NULL)
return NULL;
//插入
if (((*p)->light) == NULL && ((*p)->right) == NULL)
{
struct tree1* new1 = (struct tree1*)malloc(sizeof(struct tree1));
new1->light = new1->right = NULL;
new1->data = a;
if (strcmp(&a, &((*p)->data)) > 0)
{
((*p)->right) = new1;
}
else
{
((*p)->light) = new1;
}
return new1;
} if (strcmp(&a, &(*p)->data) > 0)
{
enter_node(a, &((*p)->right));
}
else
{
enter_node(a, &((*p)->light));
} }
void del_node(struct tree1* p)
{
struct tree1* father;//临时的存储的父节点
struct tree1** father1;//真正的父节点
p = del_node1; if (p->light == NULL || p->right == NULL)//删除叶子结点 free(p);
if (p->light != NULL && p->right == NULL || p->right != NULL && p->light == NULL)//只有一个结点
{
father = find_father(root);//接收该节点的父节点
father1 = &father;
//判断是父节点的哪个方向的儿子
if (father->light == p)
{
if (p->light == NULL)
{
(*father1)->light = p->right;
}
else
{
(*father1)->light = p->light;
}
}
else
{
if (p->light == NULL)
{
(*father1)->right = p->right;
}
else
{
(*father1)->right = p->light;
}
}
} } struct tree1* find_father(struct tree1* p)
{
if (p == NULL)
{
return NULL;
}
if (p->light == del_node1 || p->right == del_node1)
{
return p;
}
find_father(p->light);
find_father(p->right);
}
int find_layer(struct tree1* p, char a, int n)
{
int c,g;
int b=0;//判断是否有该节点
if (p == NULL)
{
return 0 ;
}
if(p->data==a)
{
return n;
}
c=find_layer(p->light, a, n + 1);
g=find_layer(p->right, a, n + 1);
if (c >= g)
{
return c;
}
else
{
return g;
} }
int find_node(struct tree1* p, char a)
{
if (p->data == a)
{
return 1;
}
if (p = NULL)
{
return 0;
}
int c, g;
c = find_node(p->light, a);
g = find_node(p->right, a);
if (c >= g)
{
return c;
}
else
{
return g;
}
}
c语言数据结构 树的基本操作的更多相关文章
- Avl树的基本操作(c语言实现)
#include<stdio.h> #include<stdlib.h> typedef struct AvlNode *Position; typedef struct Av ...
- 图解数据结构树之AVL树
AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节点的两个子 ...
- ACM数据结构-树状数组
模板: int n; int tree[LEN]; int lowbit(int x){ return x&-x; } void update(int i,int d){//index,del ...
- Python入门篇-数据结构树(tree)的遍历
Python入门篇-数据结构树(tree)的遍历 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.遍历 迭代所有元素一遍. 二.树的遍历 对树中所有元素不重复地访问一遍,也称作扫 ...
- Python入门篇-数据结构树(tree)篇
Python入门篇-数据结构树(tree)篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.树概述 1>.树的概念 非线性结构,每个元素可以有多个前躯和后继 树是n(n& ...
- [HNOI2004]L语言 字典树 记忆化搜索
[HNOI2004]L语言 字典树 记忆化搜索 给出\(n\)个字符串作为字典,询问\(m\)个字符串,求每个字符串最远能匹配(字典中的字符串)到的位置 容易想到使用字典树维护字典,然后又发现不能每步 ...
- 15、R语言聚类树的绘图原理
聚类广泛用于数据分析.去年研究了一下R语言聚类树的绘图原理.以芯片分析为例,我们来给一些样品做聚类分析.聚类的方法有很多种,我们选择Pearson距离.ward方法. 选择的样品有: "GS ...
- 常见基本数据结构——树,二叉树,二叉查找树,AVL树
常见数据结构——树 处理大量的数据时,链表的线性时间太慢了,不宜使用.在树的数据结构中,其大部分的运行时间平均为O(logN).并且通过对树结构的修改,我们能够保证它的最坏情形下上述的时间界. 树的定 ...
- 数据结构和算法(Golang实现)(17)常见数据结构-树
树 树是一种比较高级的基础数据结构,由n个有限节点组成的具有层次关系的集合. 树的定义: 有节点间的层次关系,分为父节点和子节点. 有唯一一个根节点,该根节点没有父节点. 除了根节点,每个节点有且只有 ...
- Java数据结构和算法(二)树的基本操作
Java数据结构和算法(二)树的基本操作 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 一.树的遍历 二叉树遍历分为:前序遍 ...
随机推荐
- python func_timeout 设置函数超时退出
使用func_timeout设置函数超时退出,使用func_set_timeout装饰器和func_timeout方法 from func_timeout import func_set_timeou ...
- oracl ocp认证到底有没有用!!!
从一个网友听说有个OCP专家认证,我们本地也有,要1万3,问题是我想真的学东西而不是为了考证,不知道这个培训能学到多少呀.
- cximage第一讲demo.cpp
使用流程可参考: https://blog.csdn.net/wxc237786026/article/details/41171079 BOOL CDemoApp::InitInstance() { ...
- TexturePacker基本使用
生成后
- 1140. 石子游戏 II (Medium)
问题描述 1140. 石子游戏 II (Medium) 爱丽丝和鲍勃继续他们的石子游戏.许多堆石子 排成一行,每堆都有正整数颗石子 piles[i].游戏以谁手中的石子最多来决出胜负. 爱丽丝和鲍勃轮 ...
- C++实现有序表--链表的合并操作代码
#include<iostream>#include<cstdlib>using namespace std;#define MAXSIZE 100#define OK 1#d ...
- VUE2.0 脚手架搭建项目,如何配置本地IP地址访问项目,详解
1.首先找到config文件夹目录下的 index.js文件 // Various Dev Server settings //host: 'localhost' //将localhost进行替换成 ...
- git拉取本地或者分支
拉取本地 git clone 拉取的仓库地址 新建一个文件夹,然后右键 拉取分支到本地 也是新建一个文件夹右键点击 Git Bash Here 然后输入 git clone -b 分支名称 分支地址 ...
- java-正确打日志
使用 slf4j 使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一. 实现方式统一使用: Logback 框架 打日志的正确方式 什么时候应该打日志 当你遇到问题的时候,只能通过 debu ...
- kafka常用命令(zookeeper与bootstrap-server)
在 0.9.0.0 之后的 Kafka,出现了几个新变动,一个是在 Server 端增加了 GroupCoordinator 这个角色,另一个较大的变动是将 topic 的 offset 信息由之前存 ...