算法_树和二叉树简介

1、树html

一、什么是树?node

树状图是一种 数据结构,它是由n(n>=1)个有限节点组成一个具备层次关系的 集合。把它叫作“树”是由于它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具备如下的特色:
每一个节点有零个或多个子节点;没有父节点的节点称为根节点;每个非根节点有且只有一个父节点;除了根节点外,每一个子节点能够分为多个不相交的子树;
树(tree)是包含n(n>0)个结点的有穷集,其中:
(1)每一个元素称为结点(node);
(2)有一个特定的结点被称为根结点或树根(root)。
(3)除根结点以外的其他数据元素被分为m(m≥0)个互不相交的集合T1,T2,……Tm-1,其中每个集合Ti(1<=i<=m)自己也是一棵树,被称做原树的子树(subtree)。
 
二、相关术语
  • 节点的度:一个节点含有的子树的个数称为该节点的度;
  • 叶节点或终端节点:度为0的节点称为叶节点;
  • 非终端节点或分支节点:度不为0的节点;
  • 双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
  • 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
  • 兄弟节点:具备相同父节点的节点互称为兄弟节点;
  • 树的度:一棵树中,最大的节点的度称为树的度;
  • 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
  • 树的高度或深度:树中节点的最大层次;
  • 堂兄弟节点:双亲在同一层的节点互为堂兄弟;
  • 节点的祖先:从根到该节点所经分支上的全部节点;
  • 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
  • 森林:由m(m>=0)棵互不相交的树的集合称为森林;

2、二叉树数据库

一、什么是二叉树?数据结构

二叉树,就是度不差过2的树(节点最多有两个叉)app

3、两种特殊的二叉树spa

一、满二叉树.net

一个二叉树,若是每个层的结点数都达到最大值,则这个二叉树就是满二叉树。指针

二、彻底二叉树code

叶节点只能出如今最下层和次下层,而且最下面一层的结点都集中在该层最左边的若干位置的二叉树htm

满二叉树必定是彻底二叉树,可是彻底二叉树不必定是满二叉树

3、二叉树的存储方式

一、链式存储方式

a、二叉树的链式存储:将二叉树的节点定义为一个对象,节点之间经过相似链表的连接方式来链接。

b、节点定义

class BiTreeNode:
    def __init__(self,data):  #data就是传进去的节点的值
        self.data = data
        self.lchild = None
        self.rchild = None

c、二叉树的遍历:

I 、先(前)序遍历:访问根结点的操做发生在遍历其左右子树以前

   具体操做:若二叉树非空,则依次执行以下操做:
  • ⑴ 访问根结点;
  • ⑵ 遍历左子树;
  • ⑶ 遍历右子树。

II、中序遍历:访问根结点的操做发生在遍历其左右子树之中(间)。

     具体操做: 若二叉树非空,则依次执行以下操做:
  • ⑴遍历左子树;
  • ⑵访问根结点;
  • ⑶遍历右子树。

III、后序遍历:访问根结点的操做发生在遍历其左右子树以后。

      若二叉树非空,则依次执行以下操做:
  • ⑴遍历左子树;
  • ⑵遍历右子树;
  • ⑶访问根结点。

IV、层次遍历

用一个队列保存被访问的当前节点的左右孩子以实现层序遍历。

二叉树的遍历代码以下

from collections import deque   #双向队列
from queue import Queue    #单向队列

# import queue
# q = queue.Queue()
# q.put('ggg')
# q.get()
class BiTreeNode:
    def __init__(self,data):
        self.data = data
        self.lchild = None
        self.rchild = None

    @classmethod
    def pre_order(self,root):
        '''前序遍历(根左右)'''
        if root: #若是有根节点
            print(root.data,end='')
            self.pre_order(root.lchild)
            self.pre_order(root.rchild)

    @classmethod
    def in_order(self,root):
        '''中序遍历(左根右)'''
        if root:
            self.in_order(root.lchild)
            print(root.data,end='')
            self.in_order(root.rchild)

    @classmethod
    def out_order(self, root):
        '''后序遍历(左右根)'''
        if root:
            self.out_order(root.lchild)
            self.out_order(root.rchild)
            print(root.data, end='')

    @classmethod
    def level_order(self,root):
        '''层次遍历(第一层,第二层,第三层...借助队列来实现)'''
        queue = deque()
        queue.append(root)
        while len(queue) > 0:
            node = queue.popleft()
            print(node.data,end='')
            if node.lchild:
                queue.append(node.lchild)
            if node.rchild:
                queue.append(node.rchild)



#建立二叉树
a = BiTreeNode("A")
b = BiTreeNode("B")
c = BiTreeNode("C")
d = BiTreeNode("D")
e = BiTreeNode("E")
f = BiTreeNode("F")
g = BiTreeNode("G")
e.lchild = a
e.rchild = g
a.rchild = c
c.lchild = b
c.rchild = d
g.rchild = f
root = e

#查看前序遍历的结果
BiTreeNode.pre_order(root)   #EACBDGF
print('')
BiTreeNode.in_order(root)    #ABCDEGF
print('')
BiTreeNode.out_order(root)  #BDCAFGE
print('')
BiTreeNode.level_order(root)  #EAGCFBD

二、顺序存储方式

如上图二叉树标出了元素所对应的索引,那么能够有一下结论

一、父节点和左孩子节点的编号下标有什么关系?

若是已知父亲节点为i,那么他的左孩子节点为2i+1

二、父节点和右孩子节点的编号下标有什么关系?

三、反过来知道孩子找父亲

(n-1)/2=i  # 左孩子求父节点
(n-2)/2=i  # 右孩子求父节点

4、二叉搜索树

一、定义

二叉搜索树是一棵二叉树且知足性质:设X是二叉树的一个节点。若是Y是X左子树的一个节点,那么Y.key <=X.key;

若是Y是X右子树的一个节点,那么Y.key>= X.key  (X.key表明X节点对应的值)

通俗的说也就是 若它的左子树不空,则左子树上全部结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上全部结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉搜索树。

二、原理

二叉排序树的查找过程和次优二叉树相似,一般采起二叉链表做为二叉排序树存储结构中序遍历二叉排序树可获得一个关键字的有序序列,一个无序序列能够经过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操做时,没必要移动其它结点,只需改动某个结点的指针,由空变为非空便可。搜索,插入,删除的复杂度等于树高,O(log(n)).

三、二叉搜索树的建立

可参考连接:https://visualgo.net/en/bst

四、二叉搜索树的遍历

五、二叉搜索树的查询、插入、删除

插入:

删除

好比要删除65

好比要删除66

代码实现:

 待续....

六、二叉搜索树存在的问题

存在的问题:当插入的是有序的时候,假如插入的数据特别多,找是能找到,可是是很花费时间的。

能够有如下解决办法:

  一、随机化的二叉搜索树(打乱顺序插入)

   二、AVL树

查找方法有:二分查找、二叉搜索树、哈希查找、顺序查找、斐波那契查找

5、AVL树-----扩展(了解)

一、AVL树:AVL树是一棵自平衡的二叉搜索树

二、AVL树具备如下性质:  

  • 根的左右子树的高度只差的绝对值不能超过1
  • 根的左右子树都是平衡二叉树

三、AVL的实现方式:旋转

 

6、B树

一、B树:B树是一棵自平衡的多路搜索树。经常使用于数据库的索引

 

7、其余

 

参考or转发

http://www.cnblogs.com/haiyan123/p/8400284.html

相关文章
相关标签/搜索