《数据结构专栏》


文章目录


一、认识树结构

树的定义:树是指由N(N>=0)个有限结点组成的具有层次性关系的集合,是一种简单的非线性结构。当N=0时,称为空树。

如何遍历树

前序遍历

中序遍历

后序遍历

对于前中后序遍历使用的是根节点的位置决定前中序。

层序遍历

对于层序来说就是一层一层的进行遍历,由上面一层的根节遍历后带入下一层的节点数据。可以使用一个辅助队列的容器来实现对于层序遍历。

代码实现

//层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{Queue qu;BTNode* cur;QueueInit(&qu);QueuePush(&qu, root);while (! QueueEmpty(&qu)){cur = QueueFront(&qu);putchar(cur->_data);if (cur->_left){QueuePush(&qu, cur->_left);}if (cur->_right){QueuePush(&qu, cur->_right);}QueuePop(&qu);}QueueDestory(&qu);
}

如何创建一个树?

对于二叉树的遍历就是前、中、后序遍历。对于前序和后序遍历可以快速的找到根节点。然后通过中序分辨出左右子树。实现对于树的构建。

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。
输入:abc ## de #g ## f ###
输出:c b e g d f a

构建树

输入时是一个数组来进行数据存储的,所以在建立树的节点时就需要使用一个数据记录数组下标。

避免在递归时数组的下标使用后,返回下标重置,这里需要保持数组下标一致向后走,递归出来后才会对于整个数组遍历。使用的一个前序思想建树。

typedef  struct TreeNode
{struct TreeNode* left;struct TreeNode* right;char val;
}TreeNode;TreeNode* makeTree(char* arr,int *count)
{if(arr[*count]=='#'||arr[*count]==' '){return NULL;}TreeNode* newnode=(TreeNode*)malloc(sizeof(TreeNode));newnode->val=arr[(*count)++];newnode->left=makeTree(arr, count);(*count)++;newnode->right=makeTree(arr, count);return newnode;
}void InOrder(TreeNode*root)
{if(root==NULL)return ;InOrder(root->left);printf("%c ",root->val);InOrder(root->right);
}int main()
{char arr[101];scanf("%s",arr);int count=0;TreeNode*tree=makeTree(arr, &count);InOrder(tree);return 0;
}

如何判断一颗树是否是完全二叉树?


通过对于满二叉树和完全二叉树的对比发现完全二叉树的底层叶子结点数目是从左向右依次递减的,所以高度为n-1层的数目是不变的满二叉树一样,对于完全二叉树的最后一层进行分析即可。

对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对
于序号为i的结点有:

  1. 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
  2. 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
  3. 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子

代码实现

int BinaryTreeComplete(BTNode* root)
{Queue qu;BTNode* cur;int tag = 0;QueueInit(&qu);QueuePush(&qu, root);while (! QueueEmpty(&qu)){cur = QueueFront(&qu);putchar(cur->_data);if (cur->_right && !cur->_left){return 0;}if (tag && (cur->_right || cur->_left)){return 0;}if (cur->_left){QueuePush(&qu, cur->_left);}if (cur->_right){QueuePush(&qu, cur->_right);}else{tag = 1;}QueuePop(&qu);}BinaryTreeDestory(&qu);return 1;
}

二、树的简单算法——递归

1.相同树

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的

对于题目讲解的相同理解应该是节点数据相同的数据,且左右子树结构也是相同的,对于空树的判断应该也要讨论,其中一颗树为空,另外一颗树不为空就明显不是相同的数。对于判断条件就是val值,左右子树结构,是否同时为空(判断是否都是叶子结点)。

class Solution {public:bool isSameTree(TreeNode* p, TreeNode* q) {if(p==nullptr&&q==nullptr)return true;if(p==nullptr||q==nullptr)return false;if(q->val!=p->val)return false;return isSameTree(q->left,p->left)&&isSameTree(q->right,p->right);}
};

2.镜像树

给你一个二叉树的根节点 root , 检查它是否轴对称

镜像树和解法有些类似于上面的相同树,但是又有些许差别就是对于树的结构比较他们是左子树和右子树的是对称的,使用的相同树的逻辑解题。

class Solution {public:bool issametree(TreeNode* root,TreeNode* subroot){if(root==nullptr && subroot==nullptr){return true;}if(root==nullptr || subroot==nullptr){return false;}if(root->val==subroot->val){return issametree(root->left,subroot->right) && issametree(root->right,subroot->left);}else{return false;}}bool isSymmetric(TreeNode* root) {if(root==nullptr) return true;return issametree(root->left,root->right);}
};

3.单值二叉树

题目: 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。 只有给定的树是单值二叉树时,才返回 true;否则返回 false。

对于二叉树中值的查找值是一个比较常用的算法,使用深度遍历,从左子树到后面右子树依次遍历。不能使用节点数据相加后对比左右子树。会存在左边是多节点,右边只有一个节点数据。但是左右子树的值依旧相等。所以需要从根得va来比较判断左右子树。

class Solution {public:bool isUnivalTree(TreeNode* root) {if(root==nullptr)return true;if(root->left&&root->val!=root->left->val)return false;if(root->right&&root->val!=root->right->val)return false;return isUnivalTree(root->left)&&isUnivalTree(root->right);}
};

总结

树的结构使用递归算法来进行遍历很容易理解,但是对于深度太深的树就会出现栈溢出情况。树用来存储数据显然不是一个很好的选择,容易出现歪脖子树,单只树。效率不高。可以进行后期优化成为搜索二叉树,AVL树……

这是关于“树先生“的故事相关推荐

  1. php path当局者迷,当局者迷_成语故事_有品有墨_品故事 写人生

    唐朝的元澹,字行冲,是一个很有学问的人.他曾撰写<魏典>三十篇,受到当时学者的推崇. 有一次,大臣魏光上书唐玄宗,要求把唐初名相魏征整理修订过的<类礼>(即<礼记> ...

  2. 据说看完这21个故事的人,30岁前都成了亿万富翁。你是下一个吗?

    1.甲去买烟,烟29元,但他没火柴,跟店员说:"顺便送一盒火柴吧."店员没给. 乙去买烟,烟29元,他也没火柴,跟店员说:"便宜一毛吧."最后,他用这一毛买一盒 ...

  3. 明白了这十个故事,你也就参悟了人生

    1.断箭 不相信自己的意志,永远也做不成将军. 春秋战国时代,一位父亲和他的儿子出征打仗.父亲已做了将军,儿子还只是马前卒.又一阵号角吹响,战鼓雷鸣了,父亲庄严地托起一个箭囊,其中插着一只箭.父亲郑重 ...

  4. Linux系统与我之间的故事

    2019独角兽企业重金招聘Python工程师标准>>> 说起Linux想必大家都不是很陌生的,关注这方面的不是大神就是对Linux特别热爱的人,那么接下来我给大家介绍下我和Linux ...

  5. 数据分析从头学_数据新闻学入门指南:让我们从头开始构建故事

    数据分析从头学 by Mina Demian 由Mina Demian 数据新闻学入门指南:让我们从头开始构建故事 (A Beginner's Guide to Data Journalism: Le ...

  6. 数据结构中等号表示什么_通过分析2016年最重要的252个中等故事我学到了什么...

    数据结构中等号表示什么 Medium may be struggling to find a sustainable business model, but they have years worth ...

  7. 我和freelancer不得不说的故事5 --- 心理落差

    我和freelancer不得不说的故事5 --- 心理落差 我下海之前所在的外企,是一家顶级知名IT企业,其SAP咨询服务业务规模和影响都很大,是SAP咨询界五大咨询公司之一.我从07年加入这家公司, ...

  8. 一个男人和一个女人的故事

    一个男人和一个女人的故事,开始还有点意思,后来就有想打人的冲动. his_and_her_circumstance,  彼男彼女的事情. 还是一个男人和一个女人的故事简单. 曾经看到过介绍, 夸得天花 ...

  9. HDU 4540 威威猫系列故事――打地鼠(DP)

    D - 威威猫系列故事――打地鼠 Time Limit:100MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Sub ...

最新文章

  1. numpy.where用法
  2. 黑莓作为猫带笔记本上网
  3. 手握6亿把钥匙 能否打开“智能家居”的大门?
  4. MySQL高级-索引是个什么东西?explain到底怎么用-MySQL查询优化大全
  5. windows server 2016安装oracle 10_Weblogic12.1.3.0补丁安装(win server与linux安装步骤介绍)
  6. java1.7开发环境_在Windows平台搭建Java 1.7开发环境
  7. jdbc各种数据库的连接说明
  8. 魅族官宣好消息:魅族16s Pro暮光森林终于要来了
  9. 小程序上传服务器图片压缩,微信小程序压缩图片并上传到服务器(拿去即用)...
  10. 区分const,static,readonly,volatile四个关键字
  11. !!2016/02/22——当日买入——事后追悔,总结经验,忘记了买票的初衷!
  12. echarts 自定义 tooltip
  13. android-倒计时工具类
  14. VLAN与Trunk的配置
  15. css画横线箭头_用纯CSS实现的箭头
  16. 三种时空模式下的全脑功能组织
  17. gif动态图如何制作?
  18. 亮灯泡科技php,记科学小实验《灯泡亮了》
  19. 使用Saiku+Kylin构建多维分析OLAP平台
  20. 动手深度学习——Pytorch 入门语法一

热门文章

  1. ESP8266使用blinker WiFi接入
  2. 小米B计划:提前进入硬件免费时代!
  3. JHipster学习记录 - 2 JHipster UAA
  4. java手游+刺客_自走棋手游:刺客流阵容很弱?掌握了精髓玩法,轻松上皇后
  5. 20200211 专题:hash
  6. 「Python海龟画图」利用海龟画笔绘制分形树
  7. JavaScript - ES6教程系列-李游Leo-专题视频课程
  8. 教你用最简单的方法,将数百个文件快速添加编号的方法
  9. 使用forkjoin框架分页查询所有数据的例子
  10. Java开发篇——设计模式(4)先生需要代购吗?