数据结构之二叉树练习
2014-10-09 09:49
155 查看
1.四种二叉树的遍历方式(前序/中序/后序/层序遍历)
2.求树的深度
3.非递归实现前序遍历
4.非递归遍历实现中序遍历
5.非递归实现后序遍历
6.求二叉树中第k层的节点个树
7.判断一个元素值是否在二叉树中
8.递归求二叉树的节点数
9.判断两个二叉树是否相等
10.统计树中节点数目
11.交换左右子树
总结:除了要求非递归实现的,无不使用到了递归思想(再次看到了递归的强大和威力)
完整源码:GitHub
/* * @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); else return 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时,节点个数为1 3,当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); else return TRUE; } } }
8.递归求二叉树的节点数
/* * @param BiTree T * @return int nodenum * @description:递归求二叉树的节点数 */ int NodeNum(BiTree T) { if(NULL == T) return 0; //证明树不空则至少有一个根节点 else return 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
相关文章推荐
- 【算法学习笔记】09.数据结构基础 二叉树初步练习2
- 【算法学习笔记】11.数据结构基础 二叉树初步练习4
- 【算法学习笔记】09.数据结构基础 二叉树初步练习2
- 【算法学习笔记】10.数据结构基础 二叉树初步练习3(遍历与递归复习)
- 数据结构与算法练习-二叉树
- 【算法学习笔记】08.数据结构基础 二叉树初步练习1
- 【算法学习笔记】11.数据结构基础 二叉树初步练习4
- 数据结构之二叉树 树结构练习---判断给定森林中有多少棵树(并查集)
- 【算法学习笔记】10.数据结构基础 二叉树初步练习3(遍历与递归复习)
- 【算法学习笔记】08.数据结构基础 二叉树初步练习1
- 数据结构基础练习-二叉树的镜像
- C++数据结构之二叉树非递归操作
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构之二叉树
- C++数据结构之二叉树递归操作
- 数据结构——后序线索化二叉树
- 数据结构基础(4)-->二叉树
- 数据结构与算法学习之二叉树及二叉树的相关操作
- 数据结构——树(二叉树)
- 数据结构中二叉树的三种遍历方式