考研数据结构
树🎄的代码汇总(三)
一、设计算法,将二叉树表示的表达式二叉树按中缀表达式输出,并加上相应的括号
void Expression(BiTree bt){
if(!bt) return;
if(bt->lchild){
int bracket=precede(bt->data,bt->lchild->data);
if(bracket==1) printf("(");
Expression(bt->lchild);
if(bracket==1) printf(")");
}
printf(bt->data);
if(bt->rchild){
int bracket=precede(bt->data,bt->rchild->data);
if(bracket==1) printf("(");
Expression(bt->rchild);
if(bracket==1) printf(")");
}
}
二、已知深度为h的二叉树以一维数组BT[0…2^h-2]作为其存储结构,试编写一算法,求该二叉树中叶子结点的个数
int leafNum(int bt[],int n){
int num=0;
for(int i=0;i<n;i++){
if(i<n/2){
if(bt[2*i+1]<0&&bt[2*i+2]<0){
num++;
}
}else if(bt[i]>=0){
num++;
}
}
return num;
}
三、有n个结点的完全二叉树存放在一维数组A[1…n]中,试根据此建立一棵用二叉链表表示的二叉树
BiTree creat(int A[],int i,int n){
if(i>n) return NULL;
BiTree bt;
if(i<=n){
bt=(BiNode*)malloc(sizeof(BiTree));
bt->data=A[i];
if(2*i>n){
bt->lchild=NULL;
}else{
bt->lchild=creat(A,2*i,n);
}
if(2*i+1>n){
bt->rchild=NULL;
}else{
bt->lchild=creat(A,2*i+1,n);
}
}
return bt;
}
四、以孩子兄弟链表为存储结构,请设计递归算法求树的深度
int height(CTree ct){
if(!ct) return 0;
else if (!ct->firstchild){
return max(1,height(ct->nextsibling));
}else{
int hc=height(ct->firstchild);
int hs=height(ct->nextsibling);
if(hc+1>hs){
return hc+1;
}else{
return hs;
}
}
}
五、已知有一棵二叉链表表示的二叉树,编写程序,输出从根节点到叶子节点的从最长一枝上的所有结点
void longline(BiTree bt)
{
if (!bt)
return;
BiTree Stack1[Max], p = bt, Stack[Max];
int top = -1, Stack2[Max], flag, len = -1;
while (top != -1 || p)
{
while (p)
{
Stack1[++top] = p;
Stack2[top] = 0;
p = p->lchild;
}
p = Stack1[top];
flag = Stack2[top--];
if (flag == 0)
{
Stack1[++top] = p;
Stack2[top] = 1;
p = p->lchild;
}
else
{
if(!p->lchild&&!p->rchild){
if(len<top){
len=top;
copy(Stack,Stack1);
}
}
p=NULL;
}
}
while(top!=-1){
printf(Stack[top--]->data);
}
}
六、当有一棵n个结点的二叉树按顺序存储方式存储在bt[1…n]中时,试写一个算法,求出二叉树中结点值分别为x和y的两个结点最近的公共祖先值
int Ancestor(int bt[],int n,int x,int y)
{
int i,j;
for(i=0;i<n;i++){
if(bt[i]==x)break;;
}
for(j=0;j<n;j++){
if(bt[j]==y) break;;
}
while(i!=j){
if(i>j) i=i/2;
else j=j/2;
}
return bt[i];
}
七、设森林F已经转换为二叉树形式,并采用二叉链表存储。设计算法,对该存储结构进行后序遍历森林中的第k棵树,输出遍历过程中所访问结点的数据域值
//首先从根节点开始向右找到第k-1个右孩子即为第k棵树,然后对其进行中序遍历
void inorder(BiTree bt){
if(!bt) return;
inorder(bt->lchild);
printf(bt->data);
inorder(bt->rchild);
}
void findk(BiTree bt,int k)
{
int i=0;
BiTree p=bt;
while(i<k&&p){
i++;p=p->lchild;
}
inorder(p);
}
八、设计算法返回二叉树T的先序序列的最后一个结点的指针,要求采用非递归形式,且不允许用栈
BiTree LastpreNode(BiTree bt)
{
if(!bt) return;
BiTree p=bt;
while(p){
if(p->rchild){
p=p->rchild;
}else if(p->lchild){
p=p->lchild;
}else{
return p;
}
}
return NULL;
}
九、若二叉树BT的每个结点其左、右子树都为空,或者其左、右子树都不空,则这种二叉树有时称为“严格二叉树”。由严格二叉树的前序序列和后序序列可以唯一确定该二叉树。
void creat(BiTree &bt,int pre[],int post[],int l1,int h1,int l2,int h2)
{
BiTree *p=bt;
if(l1<=h1){
p=malloc(sizeof(BiTree));
p->data=pre[l1];
if(h1==l1){
p->lchild=p->rchild=NULL;
}else{
for(int i=l2;i<=h2;i++){
if(post[i]==pre[l1+1])break;;
}
l=i-l2+1;
creat(p->lchild,pre,post,l1+1,l1+l,l2,i);
creat(p->rchild,pre,post,l1+l+1,h1,i+1,h2-1);
}
}
}
十、试编写算法,计算每层中结点data域数值大于50结点个数,并输出这些结点的data域的数值和序号
typedef struct node
{
int level,value,idx;
}*node;
void leafnum(BiTree bt)
{
if(!bt) return;
node a[Max],s;
int front=-1,rear=0,last=0,level=1,i=0,num=0;
BiTree p=bt,Queue[Max];
Queue[0]=p;
while(front<rear){
p=Queue[++front];
if(p->data>50){
s->level=level;
s->idx=i++;
s->value=p->data;
a[num++]=s;
}
if(p->lchild) Queue[++rear]=p->lchild;
if(p->rchild) Queue[++rear]=p->rchild;
if(front==last){
last=rear;
level++;
i=0;
}
}
}
十一、将二叉树的结点信息顺序存储到数组中,如某位置为空则置为null,最后返回实际的最大下标
int layer(BiTree bt,int a[]){
if(!bt) return -1;
BiTree p=bt,Queue1[Max];
int Queue2[Max],i=1,front=-1,rear=0,max=-1;
Queue1[0]=p;
Queue2[0]=i;
while(front<rear){
p=Queue1[++front];
i=Queue2[front];
a[i]=p->data;
max=i;
if(p->lchild) {
Queue1[++rear]=p->lchild;
Queue2[++rear]=2*i;
}
if(p->rchild) {
Queue1[++rear]=p->rchild;
Queue2[++rear]=2*i+1;
}
}
return max;
}