您的位置:首页 > 其它

【考研】东北大学二叉树相关算法(2)

2017-01-07 14:09 323 查看

编写一个算法,判断给定的二叉树是否是二叉排序树

keyType predt=-32767;
int JudgeBst(BiTree bt)
{
int b1,b2;
if(bt==null)
return null;
else
{
b1=JudegeBst(bt->lchild);
if(bt==0||predt>=bt->data)
return 0;
predt=bt->data;
b2=JudegeBst(bt->rchild);
return b2;
}
}


设计一个算法,求出指定结点在给定二叉树排序树中的层次

算法思想

设二叉树采用二叉链表存储结构,在二叉排序树中,查找一次就下降一层。因此查找该结点所用的次数就是该结点在二叉树中的层次采用二叉排序树非递归查找算法,用n保存查找层次,没查找一次,n就+1,直到找到相应的结点。

int level(BiTree br,BSTNode *p)
{
int n=0;
Bitree t=bt;
if(bt!=null)
{
n++;
while(t->data!=p->data)
{
if(t->data<p->data)
t=t->rchild;
else
t=t->rchild;
n++;
}
}
return n;
}


采用二叉树遍历的思维编写一个判断二叉树是否是平衡二叉树的算法

算法思想:

设置二叉树的平衡标记balance,以标记返回二叉树是否是平衡二叉树,若为平衡二叉树,返回1,否则返回0;h为二叉树的高度,采用前序遍历的递归算法。

①若bt=null 则h=0,balance=1

②bt只有根结点 h=1,balance=1;

③否则,对bt的左右子树执行递归运算,返回左右子树的高度和平衡标记,bt的高度为最高子树的高度+1,若左右子树的高度差大于1,则balance=0.若左右子树的高度差小于1,则左右子树都平衡,balance=1.否则balance=0

void Judege_AVL(BiTree bt, int &balance,int &h)
{
int b1,br,h1,hr;
if(bt==null)
{
h=0;balance=1;
}
else if(bt->lchild==null&&bt->rchild==null)
{
h=1;balance=1;
}
else
{
Judege_AVL(bt->lchild,b1,h1);
Judege_AVL(bt->rchild,b2,hr);
h=(h1>hr?h1:hr)+1;
if(abs(h1,hr)<2)
balance=b1&&br;
else
balance=0;
}
}


设计一个算法,求出给定二叉排序树中最小和最大的关键字

在一棵二叉排序树中,最左下结点即为关键字最小的结点,最右下结点即为关键字最大的结点。

keyType Minkey(BSTNode *bt)
{
while(bt->lchild!=null)
bt=bt->lchild;
return bt->data;
}
keyType Maxkey(BSTNode *bt)
{
while(bt->rchild!=null)
bt=bt->rchild;
return bt->data;
}


设计一个算法,从大到小输出二叉排序树中所有值不小于k的关键字

算法思想:

由二叉排序树的性质可知,右子树中所有结点值都大于根结点。左子树中所有结点值均小于根结点值。为了从大到小输出,县遍历右子树,再访问根结点,后遍历左子树

void OutPut(BSTNode *bt,keyType k)
{
if(bt==null)
return ;
if(bt->rchild!=null)
OutPut(bt->rchild,k);
if(bt-<data>=k)
printf("%d",bt->data);
if(bt->lchild!=null)
OutPut(bt->lchild,k);
}


编写一个递归算法,在一棵有n个结点的随机建立起来的二叉排序树中查找第k(1≤k≤n)小的元素,并返回指向该结点的指针,要求算法的平均时间复杂度为O(logaN)a为2.二叉排序树中的每个结点除data,lchild,rchild等数据成员外,增加一个count成员,保存以该结点为根的子树上的结点个数

算法思想:

设二叉排序树的根节点为*t,根据结点的存储的信息,有一下几种树的情况

★⑴若t->lchild为空

①t->rchild非空且k==1,则*t为第k小的元素

②t->rchild非空且K!=1,则第K小的元素在*t的右子树

★⑵若t->lchild非空

①t->lchild->count==k-1,则*t为第K小的元素

②t->lchild->count>k-1,则第k小的元素必在*t的左子树,继续在*t的左子树中查找

③t->lchild->count

BSTNode *search_Small(BSTNode *t,int k)
{
if(k<1||k>t->data)
return NULL;
if(t->lchild==null)
{
if(k==1)
return 1;
else
return search_Small(t->rchild,k-1);
}
else
{
if(t->lchild->count==k-1)
return t;
if(t->lchild->count>k-1)
return search_Small(t->lchild,k);
if(t->lchild->count<k-1)
return search-Small(t->lchild->count+1);
}
}


求二叉树中以值为X的结点为根的子树深度

int Get_Sub_Depth(BiTree T,int x)
{
if(T->data==x)
{
printf("%d",Get_Depth(T));
exit 1;
}
else
{
if(T->lchild)
Get_Sub_Depth(T->lchild,x);
if(T->rchild)
GEt_Sub_Depth(T->rchild,x);
}
}

int GetDepth(BiTree T)
{
if(T==null)
return 0;
else if(T->lchild==null&&T->rchild==null)
retunr 1;
else
{
int dep1=GetDepth(T->lchild);
int dep2=GetDepth(T->rchild);
if(dep1>dep2)
return dep1+1;
else
return dep2+1;
}
}


设计一棵平衡二叉树的每个结点都标明了平衡因子bf,试设计一个算法,求平衡二叉树的高度

int Heigh_bf(BiTree T)
{
levle=-;P=T;
while(P)
{
level++;
if(p->bf<0)
p=p->rchild;
else
p=p->lchild;
}
return level;
}


设二叉树的结点结构为二叉平衡树结点结构,设计一个递归算法计算并填写二叉树中每个结点的平衡因子,同时返回二叉树中不平衡结点个数

int GetDepth(BiTree T);
int Get_bf(BiTree T,int &count)
{
if(T)
{
Get_bf(T->lchild);
Get_bf(T->rchild);
m=GetDepth(T->lchild);
n=GetDepth(T->rchild);
T->bf=m-n;
if(T->bf>1||T->bf<-1)
count++;
}
}

int GetDepth(BiTree T)
{
if(T==null)
return 0;
else if(T->lchild==null&&T->rchild==null)
retunr 1;
else
{
int dep1=GetDepth(T->lchild);
int dep2=GetDepth(T->rchild);
if(dep1>dep2)
return dep1+1;
else
return dep2+1;
}
}


已知二叉树的顺序存储结构建立二叉链表结构

bool CreatrBiTree_SqlList(BiTree &T,SqList sa)
{
BiTree ptr[sa.last+1];          该数组存储于sa中各结点对应的树指针
if(!sa.last)
{
T=null;
return true;
}
ptr[1]=(BTNode *)malloc(sizeof(BTNode));
ptr[1]->data=sa.elem[1];           建立树根
T=Ptr[1];
for(i=2;i<=sa.last;i++)
{
if(!sa.elem[i])
return false;
ptr[i]=(BTNode *)malloc(sizeof(BTNode));
Ptr[i]->data=sa.elem[i];
j=i/2;                       找到结点的双亲
if(i-j*2)                    i是j的右孩子
ptr[j]->lchild=ptr[i];
}
return true;
}


假设一个仅包含二元运算符的算术表达式以二叉链表形式存放于二叉树T中,设计算法后序遍历计算表达是的值

float PostValue(BiTree T)
{
float lv,rv;
if(T)
{
lv=PostValue(T->lchild);
rv=PostValue(T->rchild);
seitch(T->optr)
{
case '+': value=lv+rv;break;
case '-': value=lv-rv;break;
case '*': value=lv*rv;break;
case '/': value=lv/rv;break;
}
return value;
}
}


设计算法利用叶子结点中空指针域将所有叶子结点链接为一个带头指针的双链表,算法返回头结点的地址

void CreateLeafList(BiTree T)
{
if(T)
{
CreateLeafList(T->lchild);
if(!T->lchild&&!T->rchild)
if(!L)
{
L=(BiTree)malloc(sizeof(BNode));
L->lchild=null;
L->rchild=T;
T->lchild=L;
pre=T;
}
else
{
Pre->rchild=T;
T->lchild=Pre;
Pre=T;
}
CreateLeafList(T->rchild);
Pre->rchild=null;
}
}


给出中序线索二叉树的结点结构,试编写不使用栈或递归的情况下,先序遍历中序线索二叉树的算法(带头结点)

void PreOrder_InThread(BiThrTree T)
{
P=T->lchild;
while(P)
{
while(p->ltag=0)
{
printf(p->data);
p=p->lchild;
}
printf(p->data);
while(p->rtag==1&&p->rchild!=T)
p=p->rchild;
if(p->rchild!=T)
p=p->rchild;
}
}


非递归不用栈中序遍历带有双亲指针的三叉链表的二叉树

三叉链表二叉树是另一种主要的链式存储结构。三叉链表的主要区别在于,它的结点比二叉链表的结点多一个指针域,该域用于存储指向本结点双亲指针

typedef struct
{
int data;
PBTNode *lchild;
PBTNode *rchild;
PBTNode *parent;
}PBTNode,*PBiTree;

void InOrder Norecurive(PBiTree T)
{
P=T;
while(P->lchild)
p=p->lchild;
while(p)
{
visit(p);
if(p->rchild)
{
p=p->rchild;
while(p->lchild)
p=p->lchild;
}
else if(p->parent->lchild==p)
{
p=p->parent;
}
else
{
p=p->parent;
while(p->parent=&&p->parent->rchild==p)
p=p->parent;
p=p->parent;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: