递归解决二叉树的问题--c语言版

二叉树的存储结构为二叉链表

typedef struct BiTNode {
    ElemType data;
    struct BiTNode *lchild,*rchild;
} BiTNode,BiTree;

判断二叉树是否为完全二叉树

bool IsComplete(BiTree bt) {
    InitQueue(Q);
    if(bt==NULL)
        return true;
    EnQueue(Q,bt);
    while(!IsEmpty(Q)) {
        DeQueue(Q,p);
        if(p) {
            EnQueue(Q,bt->lchild);
            EnQueue(Q,bt->rchild);
        } else {
            while(!IsEmpty(Q)) {
                DeQueue(Q,p);
                if(p) {
                    return false;
                }
            }
        }
    }
    return true;
}

判断两棵二叉树是否相似

bool similar(BiTree b1,BiTree b2) {
    if(b1==NULL&&b2==NULL)
        return true;
    else if(b1==NULL||b2==NULL)
        return false;
    else {
        bool lefts=similar(b1->lchild,b2->lchild);
        bool rights=similar(b1->rchild,b2->rchild);
        return lefts&&rights;
    }
}

判断两棵二叉树是否相同

bool same(BiTree b1,BiTree b2) {
    if(b1==NULL&&b2==NULL)
        return true;
    else if(b1==NULL||b2==NULL)
        return false;
    else if(b1->data!=b2->data)
        return false;
    else
        return same(b1->lchild,b2->lchild)&&same(b1->rchild,b2->rchild);
}

判断二叉树是否为二叉排序树

int prev = MIN;
bool flag = true;
bool InOrderTraverse(BiTree T) {
	if(T==NULL) {
		return flag;
	} 
	if(T->lchild != NULL && flag) {
		InOrderTraverse(T->lchild);
	}
	if(T->data<prev) {
		flag = false;
	}
	prev = T->data;
	if(T->rchild != NULL && flag) {
		InOrderTraverse(T->rchild);
	}
	return flag;
}

先、中、后、层次遍历及该结点的层次

void PreOrder(BiTree bt,int i) {
    if(bt!=NULL) {
        print("%d,%d",bt->data,i);
        PreOrder(bt->lchild,i+1);
        PreOrder(bt->rchild,i+1);
    }
}
void levelOrder(BiTree T) {
    InitQueue(Q);
    BiTree p;
    EnQueue(Q,T);
    int level=1,last=0;
    while(!IsEmpty Q) {
        DeQueue(Q,p);
        print("%d,%d",p->data,level);
        if(p->lchild)
            EnQueue(Q,p->lchild);
        if(p->rchild)
            EnQueue(Q,p->rchild);
        if (Q.front > last) {
            last = Q.rear-1;
            level++;
        }
    }
}

交换二叉树中每个结点的两个子女。

void swap(BiTree &bt) {
    if(bt) {
        swap(bt->lchild);
        swap(bt->rchild);
        int temp=bt->lchild->data;
        bt->lchild->data=bt->rchild->data;
        bt->rchild->data=temp->data;
    }
}

统计二叉树中所有结点的个数

int getCount(BiTree bt) {
    int count=0;
    if(bt!=null) {
        ++count;   //根结点+1
        count+=getCount(bt->lchild);
        count+=getCount(bt->rchild);
    }
    return count;
}

统计二叉树中度为0、1、2的结点个数。

int getCount(BiTree bt) {
    if(bt==NULL)
        return 0;
    int count=0;
    if(bt->lchild==NULL&&bt->rchild==NULL)
        //if(bt->lchild!=NULL&&bt->rchild==NULL || bt->lchild==NULL&&bt->rchild!=NULL)
        //if(bt->lchild!=NULL&&bt->rchild!=NULL)
        count=1;
    return count+getCount(bt->lchild)+getCount(bt->rchild);
}
//统计二叉树中第k层结点的个数
int K_level(BiTree T,int k) {
    InitQueue(Q);
    BiTree p;
    EnQueue(Q,T);
    int level=1,last=0,count=0;
    while(!IsEmpty Q &&level<=k) {
        DeQueue(Q,p);
        if(level==k)
            count++;
        if(p->lchild)
            EnQueue(Q,p->lchild);
        if(p->rchild)
            EnQueue(Q,p->rchild);
        if (Q.front > last) {
            last = Q.rear-1;
            level++;
        }
    }
    return count;
}

计算二叉树中各结点中的最大、最小元素的值。

void maxValue(BiTree bt,int &max) {
    if(bt!=NULL) {
        //if(bt->data<max)
        if(bt->data>max)
            max=bt->data;
        maxValue(bt->lchild,max);
        maxValue(bt->rchild,max);
    }
}

统计二叉树的高度

int getDepth(BiTree bt) {
    if(bt==NULL)
        return 0;
    int ldep=getDepth(bt->lchild);
    int rdep=getDepth(bt->rchild);
    return 1+(ldep>rdep?ldep:rdep);
}

先用前序遍历求出每一层的宽度,再求出最大宽度,即树的宽度。

int levelCount(BiTree bt,int a[],int h) {
    if(bt!=NULL) {
        a[h]=a[h]+1;
        getWidth(bt->lchild,a,h+1);
        getWidth(bt->rchild,a,h+1);
    }
}
int getWidth(BiTree bt) {
    int a[16],i,wid;
    for(i=0; i<16; i++)
        a[i]=0;
    levelCount(bt,a,1);
    wid=a[0];
    for(i=1; i<16; i++) {
        if(a[i]>wid)
            wid=a[i];
        return wid;
    }
}

计算指定结点*p所在的层次。

int getNodeLevel(BiTree bt,BiTNode *p) {
    if(bt==NULL)
        return 0;
    if(bt==p)
        return 1;
    int left=getNodeLevel(bt->lchild,p);
    if(left!=0)
        return left+1;
    else
        return getNodeLevel(bt->rchild,p)+1;
}

一棵具有n个结点的完全二叉树,顺序存储在数组a[n]中,找出给定结点e的双亲结点和孩子结点的值。

int findNodes(char a[],int n,char e) {
	int i;
	for(i=1; i<=n; i++) {
		if(a[i]==e)
			break;
	}
	if(i>n||i==1)
		return 0;
	//顺序存储在数组中[1~n]
	print("该结点的双亲结点为%c\n",a[i/2]);
	if(2*i<=n)
		print("该结点的左孩子结点为%c\n",a[2*i]);
	if(2*i+1<=n)
		print("该结点的右孩子结点为%c\n",a[2*i+1]);
	return 1;
}

根结点到值为x的结点的路径(查找值为x的结点,并打印值为x的结点的所有祖先)

void Search(BiTree bt,TElemType x) {
    typedef struct {
        BiTree t;
        int tag; // tag=0表示左子女被访问,tag=1表示右子女被访问
    } stack;
    stack s[100]; // 设栈容量足够大
    int top=0;
    BiTree p=bt;
    while(p!=NULL || top>0) {
        while(p!=NULL && p->data!=x) {
            s[++top].t=p;
            s[top].tag=0; // 结点入栈
            p=p->lchild; // 沿左分枝向下
        }
        if (p!=NULL && p->data==x) {
            cout<<"所查结点%d的所有祖先结点的值为:\n";
            for(int i=1; i<=top; i++)
                cout<data<<" , ";
            return; // 输出祖先值后结束
        }
        while (top!=0 && s[top].tag==1)
            top--; // 退栈(空遍历)
        if(top!=0) {
            s[top].tag=1;
            p=s[top].t->rchild; // 沿右分枝向下遍历
        }
    }
}

二叉树中和为某一值的路径

从二叉树中删掉所有叶结点。

void Delete_leaf(BiTree bt) {
    if(bt==NULL)
        return;
    BiTree p;
    if(bt->lchild) {
        p=bt->lchild;
        if(!p->lchild&&!p->rchild) {
            free(p);
            bt->lchild=NULL;
        }
    }
    if(bt->rchild) {
        p=bt->rchild;
        if(!p->lchild&&!p->rchild) {
            free(p);
            bt->rchild=NULL;
        }
    }
    Delete_leaf(bt->lchild);
    Delete_leaf(bt->rchild);
}

将二叉树的叶结点按从左到右的顺序连成一个单链表。

LinkedList head,pre=NULL;
LinkedList InOrder(BiTree b) {
	if(b) {
		InOrder(b->lchild);
		if(b->lchild==NULL&&b->rchild==NULL) {
			if(pre==NULL) {
				head=b;
				pre=b;
			} else {
				pre->rchild=b;
				pre=b;
			}
		}
		InOrder(b->rchild);
		pre->rchild=NULL;
	}
	return head;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上岸啦小王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值