(1)思想:
若树非空,目标值与根结点的值比较:
①若相等,则查找成功。
②若小于根结点,则查找左子树,若大于根结点,则查找右子树
查找成功则返回节点指针,查找失败,则返回NULL。
(2)代码:
//二叉排序树结点
typedef struct BSTNode{
int key;
struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
//在二叉排序树中查找值为key的结点(非递归)
BSTNode *BST_Search(BSTNode T,int key){
while(T!=NULL&&key!=T->key){
if(key<T->key)
T=T->lchild;
else T=T->rchild;
}
return T;
}
//在二叉排序树中查找值为key的结点(递归)
BSTNode *BSTSearch(BSTree T,int key){
if(T==NULL)
returm NULL;
if(key==T->key)
return T;
else if(key==T->key)
return BSTSearch(T->lchild,key);
else
return BSTSearch(T->rchild,key);
}
//在二叉排序树插入关键字k的新结点(递归实现)
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->rchild,k);
}
//按照str[]中的关键字序列建立二叉排序树
void Creat_BST(BSTree &T,int str[],int n){
T=NULL;
int i=0;
while(i<n){
BST_Insert(T,str[i]);
i++;
}
}
//插入结点
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->rchild,k);
}
//二叉排序树结点
typedef struct AVLNode{
int key;
int balance;//平衡因子
struct AVLNode *lchild,*rchild;
}AVLNode,*AVLTree;
(1)最小不平衡子树:从插入点往回找到第一个不平衡节点,调整以该结点的根的子树。
(2)插入后查找路径上的所有结点的平衡因子都会发生变化。
(3)寻找最小不平衡子树
(4)只需要将最小不平衡子树调整平衡,其他祖先结点都会恢复平衡。
(5)调整不平衡子树
① LL(在A的左孩子的左子树中插入导致不平衡)
右单旋转:由于在结点A的左孩子的左子树上插入了新结点,A的平衡因子从1增至2,导致以A上为根的子树失去平衡,需要一次向右的旋转操作。将A的左孩子B向右上旋转代替A成为根结点,将A结点向右下旋转成为B的右子树的根结点,而B的原右子树则作为A结点的左子树。
②RR(在A的右孩子的右子树中插入导致不平衡)
左单旋转:由于在结点A的右孩子的右子树上插入了新结点,A的平衡因子从-1增至-2,导致以A上为根的子树失去平衡,需要一次向左的旋转操作。将A的右孩子B向左上旋转代替A成为根结点,将A结点向左下旋转成为B的左子树的根结点,而B的原左子树则作为A结点的右子树。
③ LR(在A的左孩子的右子树中插入导致不平衡)
先左旋后右旋:由于在A的左孩子L的右子树R上插入新结点,A的平衡因子由1增至2,导致以A为根的子树失去平衡,需要进行两次旋转操作,先左旋后右旋。先将A结点的左孩子B的右子树的根结点C向左上旋转提升到B结点的位置,然后再把该C结点向右上旋转提升到A结点的位置。
④ RL(在A的右孩子的左子树中插入导致不平衡)
先右后左旋转
由于在A的右孩子L的左子树R上插入新结点,A的平衡因子由-1增至-2,导致以A为根的子树失去平衡,需要进行两次旋转操作,先右旋后左旋。先将A结点的右孩子B的左子树的根结点C向右上旋转提升到B结点的位置,然后再把该C结点向左上旋转提升到A结点的位置。
(6)代码
f->lchild=p->rchild;
p->rchild=f;
gf->lchild/rchild = p;
f->rchild=p->lchild;
p->lchild=f;
gf->lchild/rchild = p;
(1)结点的权:有某种现实含有的数值(如:表示结点的重要性等)
(2)结点的带权路径长度:从树的根到该结点的路径长度(经过的边数)与该结点上权值的乘积。
(3)树的带权路径长度:树中所有叶结点的带权路径长度之和wpl
(4)在含有n个带权也结点的二叉树中,其中带权路径长度最小的二叉树称为哈夫曼树,也称最优二叉树。
(1)给定n个权值分别为w1, w2,…, wn的结点,构造哈夫曼树的算法描述如下:
1)将这n个结点分别作为n棵仅含一个结点的二叉树,构成森林F。
2)构造一个新结点,从F中选取两棵根结点权值最小的树作为新结点的左、右子树,并且将新
结点的权值置为左、右子树上根结点的权值之和。
3)从F中删除刚才选出的两棵树,同时将新得到的树加入F中。
4)重复步骤2)和3),直至F中只剩下一棵树为止。
(2)规律:
100个选择题的答案
(1)固定长度编码——每个字符用相等长度的二进制位表