二叉树的基本概念
关于二叉树有一点需要注意:二叉树并不是树的一种特殊形式,二叉树时有序树。
二叉树又有几种特殊的形式:最优二叉树(哈弗曼树)、二叉判定树、二叉排序树(二叉查找树)、二叉堆
哈弗曼树
哈弗曼树的特点就是带权路径长度最小,因此还叫最优二叉树。
【哈夫曼树的构造】
根据哈弗曼树的定义,一棵二叉树要使其WPL值最小,必须使权值越大的叶子结点越靠近根结点,而权值越小的叶子结点越远离根结点。算法如下:
假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:
(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);
(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;
(3)从森林中删除选取的两棵树,并将新树加入森林;
(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。
例如:
原理:对于有序的查找表,可采用折半查找,因为查找表中的元素是有序的,我们可以先确定待查元素所在查找表中的范围,然后逐步缩小查找范围直到找到或找不到为止。
算法实现:
int SearchBin(int arr[],int key){ int low=0; int high=arr.length; while(low<high){ int mid=(low+high)/2; if(arr[mid]==key) return mid; else if(arr[mid]>key) high=mid-1; else low=mid+1; } }
折半查找每进行一次比较,元素下次查找的范围将缩小为原来的一半,因此查找长度不会超过logn +1(也是树的深度),即运行时间最坏情况是O(logn)。
二叉排序树
又称“二叉查找树”、“二叉搜索树”。或者是一棵空树;或者是具有下列性质的二叉树:
1、若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2、若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3、左、右子树也分别为二叉排序树;
二叉排序树通常采用二叉链表作为存储结构。中序遍历二叉排序树可得到一个依据关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即是对无序序列进行排序的过程。二叉判定树就是一棵二叉排序树。
查找性能介于O(logn),O(n)(数列有序,树退化成线性表,如右斜树)。
平衡树
平衡二叉树又称AVL树。它或者是颗空树,或者是具有下列性质的二叉树:
1、它的左子树和右子树都是平衡二叉树,
2、左子树和右子树的深度之差的绝对值不超过1。
若将二叉树节点的平衡因子BF定义为该节点的左子树的深度减去它的右子树的深度,则平衡二叉树上所有节点的平衡因子只可能为-1,0,1.只要二叉树上有一个节点的平衡因子的绝对值大于1,那么这颗平衡二叉树就失去了平衡。
红黑树
红黑树,一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。
通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。
红黑树的5个性质:
每个结点要么是红的要么是黑的。
根结点是黑的。
如果一个结点是红的,那么它的两个儿子都是黑的。
对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点。
每个叶结点(叶结点即指树尾端NIL指针或NULL结点)都是黑的。
正是红黑树的这5条性质,使一棵n个结点的红黑树始终保持了logn的高度,从而也就解释了上面所说的“红黑树的查找、插入、删除的时间复杂度最坏为O(log n)”这一结论成立的原因。
二叉堆
二叉堆满足二个特性:
1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。
二叉堆是一种优先队列的数据结构,具有2种性质:结构性质和堆序性。这里讨论都基于最小二叉堆,这种二叉堆对最小元素的访问非常高效。
二叉堆的ADT操作主要包括Insert(插入)和DeleteMin(删除最小元)。
【结构性质】
堆是一棵完全二叉树(若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 都被填满,第 h 层所有的结点都连续集中在最左边),如下图。
(1)因为完全二叉树很有规律,因此可以用一个数组而不需要用指针存储;
(2)对于数组中任一位置i处的元素,其左儿子在位置2*i上,右儿子在2*i+1上。也正因为这样,我们可以很方便的不用指针而只用数组就能访问左右儿子。
【堆序性】
由于我们想快速的找到最小元,因此最小元应在根上。我们可以以O(1)时间找到最小值。
堆序性指,在一个堆中,每一个节点X,X父亲中的关键字小于(或等于)X中的关键字,根节点除外(因为没有父亲)。
分类:小顶堆和大顶堆:
对于序列{k1,k2,....,kn} 有ki<=k2i且ki<=k(2i+1) 即根节点小于任意一个孩子节点,称为小顶堆 ki>=k2i且ki>=k(2i+1) 即根节点大于任意一个孩子节点,称为大顶堆。