二叉树
二叉树的基本概念和表示方法
typedef struct BiTNode{
ElemType data; //数据域
struct BiTNode *lchild,*rchild; //左、右孩子指针
} BiTNode,*BiTree;
二叉树递归遍历方法
//二叉树递归先序遍历
void PreOrder(BiTree T){
if(T!=NULL){
vist(T); // 访问根节点
PreOrder(T-lchild); //递归遍历左子树
PreOrder(T-rchild); //递归遍历右子树
}
}
//二叉树递归中序遍历
void InOrder(BiTree T){
if(T!=NULL){
InOrder(T-lchild); //递归遍历左子树
vist(T); // 访问根节点
InOrder(T-rchild); //递归遍历右子树
}
}
//二叉树递归后序遍历
void PostOrder(BiTree T){
if(T!=NULL){
PostOrder(T-lchild); //递归遍历左子树
PostOrder(T-rchild); //递归遍历右子树
vist(T); // 访问根节点
}
}
二叉树的非递归遍历方法
//二叉树中序非递归遍历
void InOrder2(BiTree T){
InitStack(S); BiTree p=T;
while(p||!IsEmpty(S)){
if(p){
Push(S,p);
p=p->lchild;
}else{
Pop(S,p); vist(p);
p=p->rchild;
}
}
}
//二叉树先续非递归遍历
void PreOrder2(BiTree T){
IniStack(S); BiTree p=T;
while(p||!IsEmpty(S)){
if(p){
visit(p);Push(S,p);
p=p->lchild;
}else{
Pop(S,p);
p=p->rchild;
}
}
}
//二叉树后续非递归遍历
void PostOrder2(BiTree T){
IniStack(S); BiTree p=T;
r=NULL;
while(p||!IsEmpty(S)){
if(p){ //走到最左
Push(S,p);
p=p->lchild;
}else{ //向右
GetTop(S,p); //读取栈顶节点(非出栈)
if(p->rchild&&p->rchild!=r) //若右子树存在,且未被访问过
p=p->rchild; //向右
else{ //否则弹出节点并访问
Pop(S,p);
visit(p);
r=p; //记录最近访问过的节点
p=NULL; //节点访问完后,重置p指针
}
}
}
}
二叉树搜索树
又称:二叉搜索树,二叉排序树
具有以下性质:
- 左子树上的节点小于根节点
- 右子树上的节点大于根节点
特点:
- 有链表的快速插入与删除操作的特点
- 有数组快速查找的优势
- 适合关键字分布随机
非递归查找
BSTNode *BST_Search(BiTree T,ElemType key){
while(T->data!=NULL&&key!=T->data){
if(T->data>key) T=T->lchild;
else T=T->rchild;
}
return T;
}
插入
int BST_insert(BiTree T,ElemType k){
if(T==null){
T=(Node)malloc(sizeof(Node));
T->data=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 if(k>T-key)
return BST_insert(T->rchild,k);
}
创建
void Creat_BST(BiTree &T,KeyType str[],int n){
T=null;
int i=0;
while(i<n){
BST_insert(T,str[i++]);
}
}
删除
删除操作的实现过程按3种情况来处理:
- 若被删除节点z是叶子节点,则直接删除.
- 若节点z只有一颗左子树或右子树,则让z的子树成为z父结点的子树,替代z的位置
- 若结点z有左右子树,则令z的直接后继(或直接前驱)代替z,然后从二叉树中删去这个直接后继(或直接前驱),这样就转换成了第一或第二种情况
平衡二叉树树
保证任意结点的左、右子树的高度差的绝对值不超过1,将这样子的二叉树成为平衡二叉树
定义结点左子树与右子树的高度差为改结点的平衡因子,平衡二叉树结点的平衡因子的值只可能是-1、0或1
平衡二叉树的调整方法
LL平衡旋转(右单旋转)
RR平衡旋转(左单旋转)
LR平衡旋转(先左后右双旋转)
RL平衡旋转(先右后左双旋转)
LR和RL旋转时,新结点究竟时插入C的左子树还是插入C的右子树不影响旋转过程