1二叉树的定义
左子树结点值<跟结点值<右子树结点值
2查找操作
typedef struct BSTNode{
int key;
struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
非递归
BSTNode *BSTree(BSTree T,int key){
while(T!=NULL&&key!=T->key){
if(key<T->key){
T=T->lchild;
}
else{
T=T->rchild;
}
return T;
}
}
递归来进行实现
BSTNode *BSTSearch(BSTree T, int key){
if(T==NULL){
return NULL;
}
if(key =T->key){
return T;
}
else{
if(key<T->key){
return BSTSearch(T->lchild, key);
}
else(key>T->key){
return BSTSearch(T->rlchild, key);
}
}
}
3插入操作
//在二叉排序树中插入关键字(递归)
//最坏空间复杂度:O(h)
int BST_Insert(BSTree &T,int k){
if(T==NULL){//原树为空,新插入的结点为根节点
T=(BSTree)malloc(sizeof(BSTNode));
T->key=k;
T->lchild=T->rchild=NULL;
return 1;
}
else{
if(k==T->key){
return 0;
}
else{
if(k<T->key){
return BST_Insert(T->lchild,k);
}
else{
return BST_Insert(T->lchild,k);
}
}
}
}
4二叉排序树的构造
void Create_BST(BSTree &T,int str[],int n){
T=NULL;
int i=0;
while(i<n){
BST_Insert(T,str[i]);
i++;
}
}
二叉排序树的删除操作:
1先搜索到目标结点,若被删除结点是叶子结点,直接删除,不会破坏二叉排序树的性质
2 若结点 z只有一颗左子树或右子树,则让结点z的子树成为z父节点的子树,替代z的位置
3若结点z左右两颗子树,则令z的直接后继(或直接前驱)替代z,然后从二叉排序树中删除这个直接后继(直接前驱),将情况转变为第一、二种情况
6查找效率分析
- 查找长度:查找运算中,需要对比关键字的次数,反映了查找操作时间复杂度;
- 查找成功的平均查找长度
ASL
- 查找失败的平均查找长度
ASL
平衡二叉树:
平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。这个方案很好的解决了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度最好情况和最坏情况都维持在O(logN)。但是频繁旋转会使插入和删除牺牲掉O(logN)左右的时间,不过相对二叉查找树来说,时间上稳定了很多。
typedef struct AVLNode{//平衡二叉树结点
int key; //数据域
int balance;//平衡因子
struct AVLNode *lchild,*rchild;
}AVLNode,*AVLTree;
结点的平衡因子=左子树高-右子树高
平衡二叉树的平衡因子的值只可能是0,1,-1
平衡二叉树插入
4种情况
在插入操作中,只要将最小不平衡子树调整平衡,则其他祖先节点都会恢复平衡
每次调整的对象都是“最小平衡子树”
灰常重要:
哈弗曼树:
定义:
在这里需要注意的是树的带权路径长度:叶子结点!!!!!!
哈弗曼树的定义:在含有n个带权结点的二叉树,其中带权路径长度(WPL)最小的二叉树称为哈弗曼树,也称最优二叉树
如何进行哈夫曼树的构造 ?
实例:(哈弗曼树不唯一)
固定长度编码:每个字符用相等长度的二进制表示
可变长度编码:允许对不同字符用不等长的二进制表示
若没有一个编码是另一个编码的前缀,则这样的编码为前缀编码