算法-树的相关算法

原创 2016年08月31日 09:50:12


树是一种递归的数据结构。树的种类从子孩子的数目上可以简单分为二叉树和多叉树。其中二叉树常见的考虑有红黑树和AVL树。另外,多叉树常见的有B树系列、Trie树系列。


有关树的算法可以从最基础的遍历(前中后层)、遍历延伸(公共祖先、对称树)、集合思想(并查集找直系亲属)。

1.遍历

遍历就是按照一定的顺序访问树的节点,由于树是非线性结构,遍历树其实就是将非线性结构转换为线性序列展示。

前、中、后遍历常有的是递归遍历和非递归遍历。

1.1递归访问的模式如下:

<span style="font-size:18px;">void Order(TreeNode *root)
{  
  if(root != NULL) 
{         //preVisit(T);         //前序访问根节点  
        Order(T->lchild);   //访问左子结点  
        //inVisit(T);           //中序访问根节点  
        Order(T->rchild);  //访问右子结点   
        //postVisit(T);        //后序访问根节点  

    }  
} </span>




1.2非递归遍历

非递归算法主要是利用循环+栈数据结构实现的。模式如下

1.2.1先序或中序遍历(非递归)

   思路:访问T->data后,将T入栈,(先序遍历左子树);遍历完左子树返回时,栈顶元素应为T,(中序遍历左子树),出栈,再遍历T的右子树。

<span style="font-size:18px;">void Order2(TreeNode* root)
{
	stack<TreeNode*> stack;
	TreeNode*p = root;//p是遍历指针
	while(p || !stack.empty())//栈不空或者p不空时循环
<span style="white-space:pre">	</span>{
		if(p != NULL)
<span style="white-space:pre">		</span>{
			stack.push(p);//存入栈中	
			//preVisit(p);//前序遍历访问根节点
			p = p->lchild;//遍历左子树
		}
		else
<span style="white-space:pre">		</span>{	
			p = stack.top();//退栈
			//inVisit(p);//中序遍历访问根节点
			stack.pop();
			p = p->rchild;//遍历右子树
		}
<span style="white-space:pre">	</span>}
}</span>



1.2.2后序遍历.

有一篇经典的总结非递归遍历二叉树的方法  http://www.jianshu.com/p/49c8cfd07410

总结出来的模式为

<span style="font-size:18px;">void order(TreeNode *root, vector<int> &path)
{
    stack< pair<TreeNode *, bool> > s;
    s.push(make_pair(root, false));
    bool visited;
    while(!s.empty())
    {
        root = s.top().first;
        visited = s.top().second;
        s.pop();
        if(root == NULL)
            continue;
        if(visited)
        {
            path.push_back(root->val);//访问根节点
        }
        else
        {
            //s.push(make_pair(root, true));//后序遍历,访问根节点<span style="font-family: Arial, Helvetica, sans-serif;">权限开通</span>
            s.push(make_pair(root->right, false));
            //s.push(make_pair(root, true));//中序遍历,访问根节点权限开通
            s.push(make_pair(root->left, false));
            //s.push(make_pair(root, true));//前序遍历,访问根节点权限开通
        }
    }
}</span>


1.2.3层序遍历(队列)

层序遍历相对简单,采用队列思维,每层压队列,直到队列为空即可结束。

</pre><p><span style="font-size:18px;"></span></p><h2><span style="font-size:18px;">1.3公共祖先问题</span></h2><div><span style="font-size:18px;">求解公共祖先问题主要有:<span style="font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25.2px;">在线法和离线法.</span></span><p style="margin: 10px auto; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25.2px;"><span style="font-size:18px;">在线法:指每提出一次请求,便给出一次应答</span></p><p style="margin: 10px auto; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25.2px;"><span style="font-size:18px;">离线法:收集所有的请求,然后统一进行处理</span></p></div><p><span style="font-size:18px;">1.3.1采用递归方法求公共祖先</span><pre name="code" class="cpp"><span style="font-size:18px;">/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution 
{
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        if(root == NULL || root == p || root == q) return root;

        TreeNode *ltree = lowestCommonAncestor(root->left,p,q);
        TreeNode *rtree = lowestCommonAncestor(root->right,p,q);

        if(ltree && rtree) return root;

        return ltree?ltree:rtree;
    }
  
};</span>

1.3.2Tarjan算法(离线法dfs+并查集)

算法的基本思想为:任选一结点开始进行深度优先搜索dfs(若深度优先搜索结束后仍有未访问的结点,则再从中任选一点再次进行)。搜索过程中已访问的结点不再访问。搜索树的若干子树构成了图的强连通分量。

推荐一篇文章:http://blog.csdn.net/v_july_v/article/details/18312089


1.3.3RMQ算法(在线法dfs+RMQ)

 RMQ,全称为Range Minimum Query,顾名思义,则是区间最值查询,它被用来在数组中查找两个指定索引中最小值的位置。

推荐一篇文章:http://www.cnblogs.com/qianye/archive/2012/12/03/2800384.html

1.4 对称树

有关二叉树的计算题和知识

1.二叉树的深度和层数其实是一样的。 2.任意一棵树的总结点数等于总分支数+1 3.叶子结点也称叶子,度为0的结点。 相关题目: 1.      一棵二叉树第六层(根结点为第一层)的结点数最多...
  • bojie5744
  • bojie5744
  • 2014年06月14日 16:00
  • 2330

二叉树常见算法总结(一)

一、在二叉树中,找到距离最远的两个节点的距离 在二叉树中,找到距离最远的两个节点的距离。在上面的二叉树中,最远的节点的距离是:4(路径是2-3-13-5-2)。 解决思路:遍历...
  • zhouwei1221q
  • zhouwei1221q
  • 2015年08月30日 18:53
  • 2321

图的概念和关于图的几个算法

图是算法中是树的拓展,树是从上xian
  • KangRoger
  • KangRoger
  • 2014年07月19日 17:07
  • 3940

二叉树的遍历算法与相关设计

  • 2010年04月16日 18:50
  • 215KB
  • 下载

二叉树相关算法的实验验证+判别给定二叉树是否为完全二叉树。

  • 2017年12月29日 13:15
  • 3KB
  • 下载

二叉树及18个相关算法

  • 2014年04月08日 10:02
  • 3KB
  • 下载

二叉树相关算法源代码大全

  • 2009年04月22日 15:58
  • 121KB
  • 下载

决策树和相关算法PPT

  • 2010年04月09日 17:04
  • 176KB
  • 下载

决策树 (Decision Tree) 原理简述及相关算法(ID3,C4.5)

Decision Tree 决策树: 决策树是属于机器学习监督学习分类算法中比较简单的一种,决策树是一个预测模型;他代表的是对象属性与对象值之间的一种映射关系。树中每个节点表示某个对象,而每个分叉路...
  • jerry81333
  • jerry81333
  • 2016年11月11日 04:11
  • 2558

14周项目1-4平衡二叉树相关算法

/* *Copyright (c) 2017,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称:项目1-验证算法 *作 者:zangyunpeng *完成日期...
  • zangyunpeng
  • zangyunpeng
  • 2017年11月30日 11:23
  • 41
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:算法-树的相关算法
举报原因:
原因补充:

(最多只允许输入30个字)