树--一些算法总结

一、二叉树的优点:

 1. 二叉排序树是一种比较有用的折衷方案。  
  数组的搜索比较方便,可以直接用下标,但删除或者插入某些元素就比较麻烦。  
  链表与之相反,删除和插入元素很快,但查找很慢。  
  二叉排序树就既有链表的好处,也有数组的好处。  
  在处理大批量的动态的数据是比较有用。

2.文件系统数据库系统一般都采用树(特别是B树)的数据结构数据,主要为排序检索的效率。二叉树是一种最基本最典型的排序树,用于教学和研究树的特性,本身很少在实际中进行应用,因为缺点太明显了(看看教科书怎么说的)。就像冒泡排序一样,虽然因为效率问题并不实用,单不失一种教学例子的好手段。
3.平衡二叉树AVL
都有哪些应用场景:查找、插入和删除在平均和最坏情况下都是O(log n),左右子树高度差小于1

二叉树支持动态插入查找,保证操作在O(height)时间,这就是完成了哈希表不便完成的工作,动态性。但是二叉树有可能出现worst-case,如果输入序列已经排序,则时间复杂度为O(N)

4.平衡二叉树/红黑树就是为了将查找的时间复杂度保证在O(logN)范围内。
所以如果输入结合确定,所需要的就是查询,则可以考虑使用哈希表,如果输入集合不确定,则考虑使用平衡二叉树/红黑树,保证达到最大效率。

5.平衡二叉树主要优点集中在快速查找。

如果你知道SGI/STL的set/map底层都是用红黑树(平衡二叉树的一种)实现的,相信你会对这些树大有兴趣。

6.计算机的核心是计算和储存,而树有效地解决了储存的问题和计算时程序调用的问题。

      1) 计算机中的一个关键就是如何建立程序之间的调用关系。科学家们利用的结构很好地处理了这个问题,程序的递归和栈的操作实质上都是建立在树形结构的基础上的。

      2) 是可以持久化管理和储存数据的数据结构。

  实际上堆是一颗不用储存边的完全二叉树,可以通过节点间的关系展开。

7.树形结构算法设计中也有着广泛的应用,其关键在于许多算法在设计的过程中采用了分治的思想,使用了递归求解的方法或者需要遍历可行解,这些程序的运行均可用树形结构表达,辅助人们理解。

  以排序算法为例,经典的快速排序,归并排序均为递归求解,使用了分治的思想,而堆排序使用的数据结构——堆,在前文已经介绍了其与树的紧密联系。

8.树最强大的功能是进行储存查询,为此计算机科学家们创造了诸如红黑树,AVL树,B+树,字典树,堆,并查集等数据结构,它们被广泛地运用于计算机的各个方面。

缺点:

顺序存储,可能会浪费空间(在非完全二叉树的时候),但是读取某个指定的节点的时候效率比较高O(0)

链式存储,相对二叉树比较大的时候浪费空间较少,但是读取某个指定节点的时候效率偏低O(nlogn)

二、【二叉树的遍历】

深度优先搜索DFS
二叉树的前中后,层次遍历(递归实现
struct TreeNode{
    int v;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x){
        v=x;
        left = NULL;
        right = NULL;
    }
};
void preOrder(TreeNode* proot){
    if(!proot) return;
    cout<<proot->v<<" ";
    preOrder(proot->left);
    preOrder(proot->right);
}
void midOrder(TreeNode* proot){
    if(!proot) return;
    midOrder(proot->left);
    cout<<proot->v<<" ";
    midOrder(proot->right);
}
void postOrder(TreeNode* proot){
    if(!proot) return;
    postOrder(proot->left);
    postOrder(proot->right);
    cout<<proot->v<<" ";
}
void levelOrder(TreeNode* proot){
    queue<TreeNode*> arr;
    arr.push(proot);
    while(!arr.empty()){
        TreeNode* tmp = arr.front();
        cout<<tmp->v<<" ";
        if(tmp->left) arr.push(tmp->left);
        if(tmp->right) arr.push(tmp->right);
        arr.pop();
    }
}
int main()
{
  TreeNode* p1 = new TreeNode(1);
  TreeNode* p2 = new TreeNode(2);
  TreeNode* p3 = new TreeNode(3);
  TreeNode* p4 = new TreeNode(4);
  TreeNode* p5 = new TreeNode(5);
  TreeNode* p6 = new TreeNode(6);
  TreeNode* p7 = new TreeNode(7);
  TreeNode* p8 = new TreeNode(8);
  p1->left = p2;
  p2->left = p4;
  p4->left = p7;
  p1->right = p3;
  p2->right = p5;
  p3->right = p6;
  p6->right = p8;
  preOrder(p1);
  cout<<endl;
  midOrder(p1);
  cout<<endl;
  postOrder(p1);
  cout<<endl;
  levelOrder(p1);
  return 0;
}
struct TreeNode{
    int v;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x){
        v=x;
        left = NULL;
        right = NULL;
    }
};
void preOrder(TreeNode* proot){
    if(!proot) return;
    cout<<proot->v<<" ";
    preOrder(proot->left);
    preOrder(proot->right);
}
void midOrder(TreeNode* proot){
    if(!proot) return;
    midOrder(proot->left);
    cout<<proot->v<<" ";
    midOrder(proot->right);
}
void postOrder(TreeNode* proot){
    if(!proot) return;
    postOrder(proot->left);
    postOrder(proot->right);
    cout<<proot->v<<" ";
}
void levelOrder(TreeNode* proot){
    queue<TreeNode*> arr;
    arr.push(proot);
    while(!arr.empty()){
        TreeNode* tmp = arr.front();
        cout<<tmp->v<<" ";
        if(tmp->left) arr.push(tmp->left);
        if(tmp->right) arr.push(tmp->right);
        arr.pop();
    }
}
int main
  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值