数据结构——树、二叉树总结(一)

  最近在看数据结构,准备跨考计算机专业,感觉一直看书很挺无趣的。感觉一周抽出一天写写总结,刷一刷OJ还是挺快乐的一件事情,感觉现在才做这些事情有点晚了,很多大佬已经很早之前就开始了,所以我只能站在大佬的肩膀上看世界了。

  首先谈谈我总体对数据结构这们课的看法,我并没有上过这个课,听了几节课的视频,就听不下去了,可能是我不太喜欢别人讲课,再者就是这门课不太好讲吧。我第一本书看的是《大话数据结构》,这本书讲的很基础,可以像看故事书那样看。然后我就开始看书做题,《王道》和《天勤》,天勤讲的更仔细,王道的题目不错适合有点基础的。

  什么是树,没错就是我们日常生活中见到的。但是在数据结构中是倒过来的树,其实我觉得更像“根”。

  怎么种一棵树,不可避免的要知道它的存储结构,就是先找到自己要待的地方,每种数据结构都差不多。有两种存储结构,,顺序存储和链式存储。这两种我就不解释了。

 大千世界树的形状千奇百怪,什么树都有,树上这时候就会引入二叉树。有时候惯性思维,按部就班的按照书中的章节开始学,我们可以试着探索前人的研究思路。树的类型千奇百怪,规律性不容易找到,这时候前辈们研究了二叉树。其实不太明白为什么会引入这个树,肯定不是因为它“二”。我就胡思乱想了,可能是因为树的分支越多研究的起来越复杂,但是一叉树就 没必要了,因为那就是个棍。还可能就是,像二进制那样,二进制转化成其他进制,其他进制转化成二进制,二叉树也是,后面就有了,二叉树与树之间的转化。所以二叉树是研究的重点对象。

  二叉树存储结构,顺序存储和链式存储。顺序结构结构适合存储完全二叉树,存储其他的树就会造成空间浪费,现在房价那么贵,这样不太好。还是链式存储比较好

链式结构节点类型的定义

typedef struct BTNode
{
        char data;//数据域,这里的节点类型为char,可以修改成其他类型
        struct BTNode *lchild;//左指针域
        struct BTNode *rchild;// 右指针域
}BTNode;  

知道到了定义之后我们怎么用这个构建出一棵二叉树呢,很多数据结构的书只给出了一个代码段,其实我很希望就是有一种输入然后有一种输出的那种形象的例子。这里先放一个代码段,后面会有一个完整的。

BTNode* createBitree()//前序顺序建立二叉树
{
        BTNode*p;
        char c;
        cin>>c;
        if(c=='0')
        {
         p=NULL;

        }
        else
        {
        p=new BTNode;//C++中开辟新的结构体空间
        //p =(BTNode*)malloc(sizeof(BTNode));//C语言中的用法,要包含stdlib.h这个头文件
        p->data=c;
        p->lchild=createBitree();
        p->rchild=createBitree();
        }
        return p;
}

我们现在构建好了这个二叉树,大家都定居好了。我怎么能够去他们家里串门呢,这就引入了遍历,先序、中序,后序,层次。

就是先去老王家还是先去老张家的问题。

这里先给出递归的算法,因为代码太简单了,一眼就懂,感觉自己很牛逼的样子。

先序遍历

void preorder(BTNode *p)
{
        if(p!=NULL)
        {
                cout<<p->data<<" ";
                preorder(p->lchild);
                preorder(p->rchild);
        }
}

中序遍历

void inorder(BTNode *p)
{
        if(p!=NULL)
        {
                inorder(p->lchild);
                cout<<p->data<<" ";
                inorder(p->rchild);
        }
}

后续遍历

void postorder(BTNode *p)
{
        if(p!=NULL)
        {
                postorder(p->lchild);
                postorder(p->rchild);
                cout<<p->data<<" ";
        }
}

完整的构建与遍历

#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct BTNode
{
        char data;//数据域,这里的节点类型为char,可以修改成其他类型
        struct BTNode *lchild;//左指针域
        struct BTNode *rchild;// 右指针域
}BTNode;
BTNode* createBitree()//前序顺序建立二叉树
{
        BTNode*p;
        char c;
        cin>>c;
        if(c=='0')
        {
         p=NULL;

        }
        else
        {
        p=new BTNode;//C++中开辟新的结构体空间
        //p =(BTNode*)malloc(sizeof(BTNode));//C语言中的用法,要包含stdlib.h这个头文件
        p->data=c;
        p->lchild=createBitree();
        p->rchild=createBitree();
        }
        return p;
}
void preorder(BTNode *p)
{
        if(p!=NULL)
        {
                cout<<p->data<<" ";
                preorder(p->lchild);
                preorder(p->rchild);
        }
}
void inorder(BTNode *p)
{
        if(p!=NULL)
        {
                inorder(p->lchild);
                cout<<p->data<<" ";
                inorder(p->rchild);
        }
}
void postorder(BTNode *p)
{
        if(p!=NULL)
        {
               postorder(p->lchild);
               postorder(p->rchild);
                cout<<p->data<<" ";
        }
}
int main()
{
   BTNode *T=NULL;
   cout<<"请创建一个二叉树"<<endl;//例如:124000300
   T=createBitree();
   cout<<"二叉树创建完成!"<<endl;
   cout<<"前序遍历二叉树"<<endl;
   preorder(T);
   cout<<endl;
   cout<<"中序遍历二叉树"<<endl;
   inorder(T);
   cout<<endl;
   cout<<"后序遍历二叉树"<<endl;
   postorder(T);
   return 0;

}

这三种遍历用递归非常简单,但是很低效。为什么低效呢,我觉得简单粗暴往往会牺牲其他东西,我们不累了,电脑就会骂街了。所以下面要用非递归的算法来搞定。这里我要引用《天勤》书里面大佬的解释“递归函数申请是系统栈,是一个所有递归函数都通用的栈,对于二叉树深度优先遍历算法,系统栈除了记录访问的节点信息外,还有其他信息要记录,以实现函数的递归调用,而用户自己定义的栈仅保存了遍历所需的节点信息,是遍历设计算法一个针对性的设计,也就是一般情况下,专业的比通用的要好一些”。

那么就研究研究非递归的遍历,感觉还挺多的,如果写在一篇上感觉没耐心看下去,下篇见

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值