我们亲爱的项目经理真是有创意,他说你给我写得二叉树挺好的;

功能还算可以:插入节点,能够删除节点;

可是有时候我们只是需要查找树的某个节点是否存在;

所以我希望你能够给我一个find功能;

还有就是,我在跟BOSS交流的时候,他根本不相信你已经把链表写成树的结构啦;

他希望你能够更明显的把树的结构打印出来;

所以,你需要实现一个show功能;

这应该不难吧;

Problem

我们需要实现的其实是遍历的两个变体;

首先确定我们的思路,想到都是需要遍历的;

那么我们是不是又想到了有递归的方式和非递归的方式呢;

int find_recursive(Node *root, int data)
{
//TODO
}

我们首先实现的是递归的,大致的结构应该是这样的;

还记得吗?递归的前面几行一般是递归的结束条件;

因此,我们的代码应该是这样的:

int find_recursive(Node *root, int data)
{
if(root == NULL)
return ;
}

其次,我们应当考虑找到目标的时候,应该是怎么确定的呢?

应该是root->data 与参数data相等的时候,我们希望程序返回啦;

因此,我们需要的代码可能会是这样的;

int find_recursive(Node *root, int data)
{
if(root == NULL){
return ;
}else if(root->data == data){
return ;
}
}

那,在当前的节点上如果没有找到目标呢;

我们需要的应该是确定往左找还是往右找;

所以需要把代码写成如下的形式;

int find_recursive(Node *root, int data)
{
if(root == NULL){
return ;
}else if(root->data == data){
return ;
}else{
int dir = root->data < data;
return find_recursive(root->link[dir],data);
}
}

dir的值只能是0或者1,代表的意义是什么大家应该很清楚啦;

它的作用是什么也应该很清楚啦;

最后执行递归;

通常我们需要客户操作的是树,因此我们需要一个包装函数;

int find(Tree *tree,int data)
{
return find_recursive(tree->root,data);
}

好啦,我们可以测试一下啦;

我首先把需要用到得代码附上;

#include <stdio.h>
#include <stdlib.h>
#include <time.h> typedef struct _node {
int data;
struct _node *link[];
}Node; typedef struct _tree{
struct _node *root;
}Tree; Tree * init_tree()
{
Tree *temp = (Tree*)malloc(sizeof(Tree));
temp->root = NULL;
return temp;
} Node * make_node(int data)
{
Node *temp = (Node*)malloc(sizeof(Node));
temp->link[] = temp->link[] = NULL;
temp->data = data;
return temp;
} int insert(Tree *tree, int data)
{
if(tree->root == NULL){
tree->root = make_node(data);
}else{
Node * it = tree->root;
int dir ;
for(;;){
dir = it->data < data;
if(it->data == data){
return ;
}else if(it->link[dir] == NULL){
break;
}
it = it->link[dir];
}
it->link[dir] = make_node(data);
}
return ;
}

测试主函数代码如下:

int main(void)
{
Tree * tree = init_tree();
insert(tree,);
insert(tree,);
insert(tree,);
insert(tree,);
printf("looking for %d...%s\n",,find(tree,) ? "Got it":"Not exist");
printf("looking for %d...%s\n",,find(tree,) ? "Got it":"Not exist");
return ;
}

运行结果如下:

好啦!可能对于客户来说,这样把查询的数据写死啦,并把那么好;

别人可能想查某个数据就输入某个数据,可能更实用;

这是非常简单的功能,我不会去讲解,但是也附上一份简单的实现;

大家写的肯的能够更加漂亮;

void tips(){
time_t curTime;
struct tm *ts;
time_t testTime = time(&curTime);
ts = localtime(&curTime);
//struct tm *tsgm = gmtime(&curTime);
puts("*************************************************************");
printf("Date:%s",asctime(ts));
puts("Please input right cmd");
puts("1)Search");
puts("2)Quit");
puts("*************************************************************");
} int search(Tree *tree)
{
char cmd;
int isExist;
int target;
tips();
while((cmd=getchar())!=EOF){
if(cmd==''){
puts("-------------------------------------------------------------");
printf("Please input the target:");
scanf("%d",&target);
isExist=find(tree,target);
if(isExist){
printf("Target %d is exists \n",target);
puts("-------------------------------------------------------------");
puts("\n");
continue;
//break;
}else{
puts("Target Not exitst");
puts("-------------------------------------------------------------");
puts("\n");
continue;
//break;
}
}else if(cmd==''){
puts("bye~");
break;
}else{
tips();
}
}
return ;
}

运行结果如下:

这个可能用户体验要较好些;

注意别忘记包涵头文件time.h

好啦查询工作算是完成啦;

接下来是下一个任务;

Problem

为啦更加形象的表明我们一直在写得是一棵树;

我想有必要show也就是秀秀我们的成果啦;

这次咱们先看要实现的效果,如下图;

我们的树根就是8,而~符合代表就是叶子啦;

这样旋转90°的树可能你不一定喜欢;

但是,如果你想再旋转90度的话你就自己想想吧;

好啦,接下来就是实现啦;

不管它咱们显示,咱们始终记住,我们需要遍历;

为简单,我们使用递归实现;

void structure_recursive(Node *root,int level)
{
if(root == NULL){
//TODO
}else{
//TODO;
}
}

这个遍历方式结构就怎么简单;

但是请思考思考,我们的输出到终端上得数据是先大的,然后是小的;

显然是只有中序遍历才能得到按正确的大小顺序输出;

所以我们需要记住这点哈;

void structure_recursive(Node *root,int level)
{
if(root == NULL){
//TODO
}else{
structure_recursive(root->link[],level + );
printf("%d\n",root->data);
structure_recursive(root->link[],level + );
}
}

你会发现,我首先写else部分,仔细看看else部分你会发现我们的中序遍历很明显啦;

可是呢!!它又有别于我们前面写得中序遍历方式,我们首先从右子树下手啦;

以前都是从左子树的,这就是为什么我们输出的结果是从大到小往下的啦;

好啦!TODO到底应该写成什么样子呢?

想想要是我们一直递归到最后要是递归一次我们就得增加一个level的计数;

到最后发现叶子是NULL我们就直接输出level个tab然后跟一个~表示叶子;

所以代码如下:

void structure_recursive(Node *root,int level)
{
   int i;
if(root == NULL){
for(i = ;i<level;i++){
putchar('\t');
}
puts("~");
}else{
structure_recursive(root->link[],level + );
printf("%d\n",root->data);
structure_recursive(root->link[],level + );
}
}

这里已经差不多完事啦,但是我们先去写一个包装函数;

void structure(Tree *tree)
{
structure_recursive(tree->root,);
}

注意包装函数里面的0表示是从最左边开始打印的;

我们先不去完善我们的structure_recursive函数,我们直接测试,看看结果;

这个可不是我们想看到的结果哈;

原因是什么呢;

我们还没有完善我们的函数呢;

void structure_recursive(Node *root,int level)
{
int i;
if(root == NULL){
for(i = ;i<level;i++){
putchar('\t');
}
puts("~");
}else{
structure_recursive(root->link[],level + );
for(i = ;i < level;i++){
putchar('\t');
}
printf("%d\n",root->data);
structure_recursive(root->link[],level + );
}
}

好啦,我们的效果出来啦;

好啦!工作完成啦;

总结一下吧;

不,还没有到总结的时候;

明天的任务还有呢:

我们的树不能一直老想着用递归实现,在很多时候它是受限制的;

递归对空间要求特别多,所以我们下次想想有没有非递归的方法实现其他的函数;

最后附上我们今天所有代码吧:

#include <stdio.h>
#include <stdlib.h>
#include <time.h> typedef struct _node {
int data;
struct _node *link[];
}Node; typedef struct _tree{
struct _node *root;
}Tree; Tree * init_tree()
{
Tree *temp = (Tree*)malloc(sizeof(Tree));
temp->root = NULL;
return temp;
} Node * make_node(int data)
{
Node *temp = (Node*)malloc(sizeof(Node));
temp->link[] = temp->link[] = NULL;
temp->data = data;
return temp;
} int insert(Tree *tree, int data)
{
if(tree->root == NULL){
tree->root = make_node(data);
}else{
Node * it = tree->root;
int dir ;
for(;;){
dir = it->data < data;
if(it->data == data){
return ;
}else if(it->link[dir] == NULL){
break;
}
it = it->link[dir];
}
it->link[dir] = make_node(data);
}
return ;
}
int remove_node(Tree *tree, int data)
{
if(tree->root != NULL)
{
Node *p = NULL;
Node *succ;
Node *it = tree->root;
int dir;
for(;;){
if( it == NULL){
return ;
}else if(it->data == data){
break;
}
dir = it->data < data;
p = it;
it = it->link[dir];
}
/***********************************************************************/ if(it->link[] != NULL && it->link[] != NULL){
p = it;
succ = it->link[];
while(succ->link[] != NULL){
p = succ;
succ = succ->link[];
}
it->data = succ->data;
p->link[p->link[] == succ] = succ->link[];
free(succ);
/***********************************************************************/
}else{ /*it->link[0] == NULL || it->link[1] == NULL */
dir = it->link[] == NULL;
if( p == NULL){
tree->root = it->link[dir];
}else{
p->link[p->link[] == it] = it->link[dir];
}
free(it);
}
} return ;
}
int find_recursive(Node *root, int data)
{
if(root == NULL){
return ;
}else if(root->data == data){
return ;
}else{
int dir = root->data < data;
return find_recursive(root->link[dir],data);
}
} int find(Tree *tree,int data)
{
return find_recursive(tree->root,data);
} void tips(){
time_t curTime;
struct tm *ts;
time_t testTime = time(&curTime);
ts = localtime(&curTime);
//struct tm *tsgm = gmtime(&curTime);
puts("*************************************************************");
printf("Date:%s",asctime(ts));
puts("Please input right cmd");
puts("1)Search");
puts("2)Quit");
puts("*************************************************************");
}
int search(Tree *tree)
{
char cmd;
int isExist;
int target;
tips();
while((cmd=getchar())!=EOF){
if(cmd==''){
puts("-------------------------------------------------------------");
printf("Please input the target:");
scanf("%d",&target);
isExist=find(tree,target);
if(isExist){
printf("Target %d is exists \n",target);
puts("-------------------------------------------------------------");
puts("\n");
continue;
//break;
}else{
puts("Target Not exitst");
puts("-------------------------------------------------------------");
puts("\n");
continue;
//break;
}
}else if(cmd==''){
puts("bye~");
break;
}else{
tips();
}
}
return ;
} void structure_recursive(Node *root,int level)
{
int i;
if(root == NULL){
for(i = ;i<level;i++){
putchar('\t');
}
puts("~");
}else{
structure_recursive(root->link[],level + );
for(i = ;i < level;i++){
putchar('\t');
}
printf("%d\n",root->data);
structure_recursive(root->link[],level + );
}
} void structure_recursive(Node *root,int level)
{
int i;
if(root == NULL){
for(i = ;i<level;i++){
putchar('\t');
}
puts("~");
}else{
structure_recursive(root->link[],level + );
for(i = ;i < level;i++){
putchar('\t');
}
printf("%d\n",root->data);
structure_recursive(root->link[],level + );
}
} void structure(Tree *tree)
{
structure_recursive(tree->root,);
} int main(void)
{
Tree * tree = init_tree();
insert(tree,);
insert(tree,);
insert(tree,);
insert(tree,);
insert(tree,);
insert(tree,);
structure(tree);
return ;
}

C语言实现二叉树-03版的更多相关文章

  1. C语言实现二叉树-02版

    ---恢复内容开始--- 昨天,提交完我们的二叉树项目后,今天早上项目经理早早给我打电话: 他说,小伙子干的不错.但是为什么你上面的insert是recusive的呢? 你难道不知道万一数据量大啦!那 ...

  2. C语言实现二叉树-04版

    二叉树,通常应当是研究其他一些复杂的数据结构的基础.因此,通常我们应该精通它,而不是了解:当然,可能并不是每个人都认同这种观点,甚至有些人认为理解数据结构就行了!根本没有必要去研究如何实现,因为大多数 ...

  3. C语言实现二叉树-01版

    故事是这样开始的,项目经理有一天终于还是拍拍我肩膀说: 无论你的链表写得多么的好,无论是多么的灵活,我也得费老半天才查找到想要的数据: 这让我的工作非常苦恼,听说有一种叫做二叉树的数据结构,你看能不能 ...

  4. 数据结构与抽象 Java语言描述 第4版 pdf (内含标签)

    数据结构与抽象 Java语言描述 第4版 目录 前言引言组织数据序言设计类P.1封装P.2说明方法P.2.1注释P.2.2前置条件和后置条件P.2.3断言P.3Java接口P.3.1写一个接口P.3. ...

  5. C语言实现二叉树-利用二叉树统计单词数目

    昨天刚参加了腾讯2015年在线模拟考: 四道大题的第一题就是单词统计程序的设计思想: 为了记住这一天,我打算今天通过代码实现一下: 我将用到的核心数据结构是二叉树: (要是想了解简单二叉树的实现,可以 ...

  6. 《C++程序设计语言(英文第四版)》【PDF】下载

    <C++程序设计语言(英文第四版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382177 内容简介 本书是C++领域经典的参 ...

  7. Rust语言之HelloWorld Web版

    Rust语言之HelloWorld Web版 下面这篇文章值得仔细研读: http://arthurtw.github.io/2014/12/21/rust-anti-sloppy-programmi ...

  8. | C语言I作业03

    | C语言I作业03 标签: 18软件 李煦亮 问题 答案 这个作业属于那个课程 C语言程序设计I 这个作业要求在哪里 https://edu.cnblogs.com 我在这个课程的目标是 学会和掌握 ...

  9. R语言实战(第二版)-part 1笔记

    说明: 1.本笔记对<R语言实战>一书有选择性的进行记录,仅用于个人的查漏补缺 2.将完全掌握的以及无实战需求的知识点略去 3.代码直接在Rsudio中运行学习 R语言实战(第二版) pa ...

随机推荐

  1. S2 第二本书 深入.NET平台和C#编程 总结 by天命

    第一章 深入.NET框架 .NET框架 包含 CLR公共语言运行时 FCL框架类库 CLR(Common Language Runtime)公共语言运行时 CLS(Common Language Sp ...

  2. sendEmail的使用

    坑!坑!坑!今天又弄了一天如何发送邮件,首先用sendmail,postfix.....等,都试过了,各种报错,然后就从早上弄到现在,在群里问问题的时候,一位好心的大哥说了他用的是sendEmail, ...

  3. HttpURLConnection 下载文件

    String fileUrl = request.getRequestURL().substring(0, request.getRequestURL().indexOf("/rest&qu ...

  4. 清除SQLServer日志的两种方法

    日志文件满而造成SQL数据库无法写入文件时,可用两种方法:一种方法:清空日志.1.打开查询分析器,输入命令DUMP TRANSACTION 数据库名 WITH NO_LOG2.再打开企业管理器--右键 ...

  5. Python全栈--9 __import__ 反射和面向对象基础 self 封装 继承(多继承的顺序) 多态

    一.反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删 ...

  6. AFNetwork 作用和用法详解

    转自:http://www.cnblogs.com/mkai/p/5729685.html AFNetworking是一个轻量级的iOS网络通信类库.它建立在NSURLConnection和NSOpe ...

  7. opencv写视频

    代码: #include<opencv2/opencv.hpp> using namespace cv; #include<string> using namespace st ...

  8. POJ 1065 Wooden Sticks Greed,DP

    排序后贪心或根据第二关键字找最长下降子序列 #pragma comment(linker, "/STACK:1024000000,1024000000") #include< ...

  9. UIView.FRAMEWORK

    uiview .framework 有太多 属性到现在基本上没怎么接触,今天开始用到了就纪录一下,有空在去了解了: [self.view bringToFront:btn] 把btn 放到self.v ...

  10. SQL Server 树查询

    WITH treeAS(SELECT ParentAssetID, AssetID,1 AS x2level,nodename,CAST(nodename AS NVARCHAR(max)) x2na ...