数据结构之二叉树练习

来源:互联网 发布:淘宝体验中心 编辑:程序博客网 时间:2024/06/06 02:52



1.四种二叉树的遍历方式(前序/中序/后序/层序遍历)


/** @description:前序遍历二叉树*/Status PreOrderTraverse(BiTree T,Status (*visit) (TElemType elem)) {if(T) {if(visit(T->data))if(PreOrderTraverse(T->lchild,visit))if(PreOrderTraverse(T->rchild,visit))return OK;return ERROR;}return OK;}/** @description:中序遍历二叉树*/Status InOrderTraverse(BiTree T,Status (*visit)(TElemType elem)) {if(T) {if(InOrderTraverse(T->lchild,visit))if(visit(T->data))if(InOrderTraverse(T->rchild,visit))return OK;return ERROR;}return OK;}/** @description:后序遍历二叉树*/Status PostOrderTraverse(BiTree T,Status (*visit)(TElemType elem)) {if(T) {if(PostOrderTraverse(T->lchild,visit))if(PostOrderTraverse(T->rchild,visit))if(visit(T->data))return OK;return ERROR;}return OK;}/** @description:层序遍历* @more:利用队列,将每个节点的左右孩子入队,由于队列的性质,可按层遍历二叉树*/Status LevelOrderTraverse(BiTree T,Status (*visit) (TElemType elem)) {if(T == NULL)return ERROR;LinkQueue TreeQueue;ElemType p;InitQueue(&TreeQueue);p = T;EnQueue(&TreeQueue,p);while(!QueueEmpty(TreeQueue)) {DeQueue(&TreeQueue,&p);if(p) {visit(p->data);EnQueue(&TreeQueue,p->lchild);EnQueue(&TreeQueue,p->rchild);}}return OK;}



2.求树的深度

/** @description:二叉树的深度* @param BiTree T* @return int depth*/int BiTreeDepth(BiTree T) {int l,r;if(T) {l = BiTreeDepth(T->lchild);r = BiTreeDepth(T->rchild);return (l > r ? l : r) + 1; }return 0;}




3.非递归实现前序遍历

/** @param BiTree T* @param Status (*Visit) (TElemType)* @description:非递归实现前序遍历* @more:这里使用栈来实现,在这个实现中其实最关键是要想到先到右孩子进栈,再把左孩子进栈*/Status PreTraverse(BiTree T,Status (*Visit) (TElemType)) {LinkStack S;BiTree p;p = T;if(T != NULL)InitStack(&S);elsereturn ERROR;//将根节点进栈Push(&S,p);//栈不为空while(! StackEmpty(S)) {Pop(&S,&p);if(p) {Visit(p->data);//注意先将右孩子进栈,再将左孩子进栈,顺序不能变if(p->rchild)Push(&S,p->rchild);if(p->lchild)Push(&S,p->lchild);}}return OK;}



4.非递归遍历实现中序遍历

/** @description:非递归遍历实现中序遍历* @more:这个对我来说真心想不出来,网上看到的让我幡然醒悟其实感觉还是有一点递归的思想在里面的-->想象一下遍历完左边的后,根节点右边的遍历思路是不是一样的>>主要思路在于一直往左走到尽头,遇到空节点则弹出,遍历,接着往右走*/Status InTraverse(BiTree T,Status (*Visit) (TElemType)) {if(T == NULL)return ERROR;BiTree p;LinkStack S;p = T;InitStack(&S);//注意结束循环的条件-->当指针为空且栈为空时在跳出循环while(p || !StackEmpty(S)) {if(p) {//当左孩子的指针不为空时,一直往左走下去,并且将所走过的节点进栈Push(&S,p);p = p->lchild;}else {//遇到的的节点为空则将现在的栈顶元素弹出打印,并往右走Pop(&S,&p);Visit(p->data);p = p->rchild;}}return OK;}


5.非递归实现后序遍历

/** @description:非递归实现后序遍历*/Status PostTraverse(BiTree T,Status (*Visit) (TElemType)) {if(T == NULL)return ERROR;BiTree p,pre;//pre是用来标记上一个访问的位置的,忘记这个很容易是程序陷入死循环pre = NULL;LinkStack S;p = T;InitStack(&S);//注意结束循环的条件-->当指针为空且栈为空时在跳出循环while(p || !StackEmpty(S)) {if(p) {//当左孩子的指针不为空时,一直往左走下去,并且将所走过的节点进栈Push(&S,p);p = p->lchild;}else {//获取栈顶元素但是不弹出GetTop(S,&p);//如果右边有元素且右边的节点不是刚才访问过的就往右边走if(p->rchild != NULL && pre != p->rchild)p = p->rchild;else {Pop(&S,&p);pre = p;Visit(p->data);p = NULL;}}}}




6.求二叉树中第k层的节点个树

/** @description:求二叉树中第k层的节点个树* @more:递归思想  1.当k == 0时,节点个数为零2.当k == 1时,节点个数为13,当k > 1时,节点个数为左子树的节点个数和游子树的节点个数之和*/int NodeNumKth(BiTree T,int k) {if(k == 0)return 0;if(k == 1)return 1;return NodeNumKth(T->lchild,k - 1) + NodeNumKth(T->rchild, k - 1);}



7.判断一个元素值是否在二叉树中

/** @param BiTree T* @param TElemType elem;* @description:判断一个元素值是否在二叉树中* @more:在则返回真,否则返回假-->可知在比较过程中(比较两颗树是否等)  可先比较当前节点,再比较左子树,最后比较右子树*/Status Locate(BiTree T,TElemType elem) {if(NULL == T)return ERROR;else {if(T->data == elem)return TRUE;else {if(! Locate(T->lchild,elem))return Locate(T->rchild,elem);elsereturn TRUE;}}}




8.递归求二叉树的节点数

/** @param BiTree T* @return int nodenum* @description:递归求二叉树的节点数*/int NodeNum(BiTree T) {if(NULL == T)return 0;//证明树不空则至少有一个根节点elsereturn NodeNum(T->lchild) + NodeNum(T->rchild) + 1;}





9.判断两个二叉树是否相等

/** @param BiTree T1* @param BiTree T2* @return Status* @description:判断两个二叉树是否相等* @more:主要树为空的情况*/Status EqualBiTree(BiTree T1,BiTree T2) {int flag;//请初始化,否则当为假时,返回值未知flag = 0;if(NULL == T1 && NULL == T2)flag = TRUE;else {if(T1 != NULL && T2 != NULL) {//当前节点相等if(T1->data == T2->data)//左孩子相等if(EqualBiTree(T1->lchild,T2->lchild))//真假情况决定于右孩子flag = EqualBiTree(T1->rchild,T2->rchild);}}return flag;}




10.统计树中节点数目

/** @param BiTree T* @description:统计二叉树中叶子节点的数目* @more:所谓叶子节点即即没有左子树和右子树的节点(度为0)*/int LevesNum(BiTree T) {if(T) {//发现叶子节点if(T->lchild == NULL && T->rchild == NULL)return 1;//递归实现查找左右子树return LevesNum(T->lchild) + LevesNum(T->rchild);}return 0;}




11.交换左右子树

/** @param BiTree T* @return void* @description:递归算法将二叉树的左右子树交换*/void Exchange(BiTree T) {BiTree temp;if(T) {//交换必须从最深层开始Exchange(T->lchild);Exchange(T->rchild);//交换左右孩子节点的指针temp = T->lchild;T->lchild = T->rchild;T->rchild = temp;}}


总结:除了要求非递归实现的,无不使用到了递归思想(再次看到了递归的强大和威力)

完整源码:GitHub


0 0
原创粉丝点击