博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二叉树的前序、中序、后序、层序遍历
阅读量:5285 次
发布时间:2019-06-14

本文共 8889 字,大约阅读时间需要 29 分钟。

数据表示:

1 //二叉链表存储 2 struct BTNode3 {4     struct BTNode *LChild;    // 指向左孩子指针5     ELEMENTTYPE    data;      // 结点数据6     struct BTNode *RChild;    // 指向右孩子指针7 };

前序遍历:

1 // 递归实现 2 void PreorderTraversal(BTNode *BT) 3 { 4     if(BT!=NULL) { 5         Print(BT->data);                                // 访问根结点 6         PreorderTraversal(BT->LChild);                  // 前序遍历左子树 7         PreorderTraversal(BT->RChild);                  // 前序遍历右子树 8     } 9 }10 11 // 非递归实现12 void PreorderTraversal(BTNode *BT)13 {14     InitStack(stack, treeDeepth);                       // 初始化元素为结点指针类型的栈stack,用以保存结点的指针15     BTNode *current = BT;                               // current指向但前要访问的结点,初始时指向根结点16     while(current != NULL || !EmptyStack(stack)) {      /* current为空结点且栈空,遍历结束 */17         if(current != NULL) {                           /* 若current不是空结点 */18             Print(current->data);                       // 访问current指向的结点19             Push(stack, current);                       // 当前结点指针current压栈20             current = current->LChild;                  // 使current的左孩子成为当前结点21         } else {                                        /* 若current指向的为空结点 */22             current = Pop(stack);                       // 弹出栈顶的结点指针赋给current23             current = current->RChild;                  // 使current的右孩子成为当前结点24         }25     }26 }

中序遍历:

1 // 递归实现 2 void InorderTraversal(BTNode *BT) 3 { 4     if(BT!=NULL) { 5         InorderTraversal(BT->LChild);                   // 中序遍历左子树 6         Print(BT->data);                                // 访问根结点 7         InorderTraversal(BT->RChild);                   // 中序遍历右子树 8     } 9 }10 11 // 非递归实现12 void InorderTraversal(BTNode *BT)13 {14     InitStack(stack, treeDeepth);                       // 初始化元素为结点指针类型的栈stack,用以保存结点的指针15     BTNode *current = BT;                               // current指向但前要访问的结点,初始时指向根结点16     while(current != NULL || !EmptyStack(stack)) {      /* current为空结点且栈空,遍历结束 */17         if(current != NULL) {                           /* 若current不是空结点 */18             Push(stack, current);                       // 当前结点指针current压栈19             current = current->LChild;                  // 使current的左孩子成为当前结点20         } else {                                        /* 若current指向的为空结点 */21             current = Pop(stack);                       // 弹出栈顶的结点指针赋给current22             Print(current->data);                       // 访问current指向的结点23             current = current->RChild;                  // 使current的右孩子成为当前结点24         }25     }26 }

后序遍历:

1 // 递归实现 2 void PostorderTraversal(BTNode *BT) 3 { 4     if(BT!=NULL) { 5         PostorderTraversal(BT->LChild);                 // 后序遍历左子树 6         PostorderTraversal(BT->RChild);                 // 后序遍历右子树 7         Print(BT->data);                                // 访问根结点 8     } 9 }10 11 // 非递归实现12 void PostorderTraversal(BTNode *BT)13 {14     InitStack(stack, treeDeepth);                       // 初始化元素为结点指针类型的栈stack,用以保存结点的指针15     BTNode *current = BT;                               // current指向但前要访问的结点,初始时指向根结点16     Push(stack, current);                               // 当前结点指针current压栈17     while(current->LChild != NULL) {                    /* 从当前结点出发,逐步找到二叉树左边结点并依次进栈 */18         current = current->LChild;19         Push(stack, current);20     }21     while(!EmptyStack(stack)) {                         /* 一直进行到栈空为止,整棵二叉树遍历完成 */22         current = Pop(stack);                           // 栈顶结点退栈作为当前结点23         if(current < 0) {                       /* 若当前结点指针标志为“负”,表示该结点的右子树已遍历完,应该访问该结点 */ 24             current = -current;                 /******* 对指针加正负号,OK,学习了,竟然这样子来标识 *******/25             Print(current->data);26         } else {                                /* 若当前结点标志为“正”,表示该结点的左子树已遍历完,应该遍历其右子树 */27             Push(stack, -current);                      // 对当前结点指针加左子树已遍历标志并入栈28             if(current->RChild != NULL) {               // 若当前结点有右子树,以右孩子作为当前结点,从它出发做后序遍历29                 current = current->RChild;30                 Push(stack, current);31                 while(current->LChild != NULL) {32                     current = current->LChild;33                     Push(stack, current);34                 }35             }36         }37     }38 }39 40 /*41  * 非递归实现  双栈42  * 思路:43  *  按“左-右-根”顺序遍历二叉树的顺序与按“根-右-左”顺序遍历二叉树的顺序正好相反44  *  所以,将按“根-右-左”顺序遍历二叉树的结点依次压入postStack栈中,遍历完后再45  *  输出postStack栈中所有的元素结点所对应的值即是按“左-右-根”顺序遍历二叉树的顺序46  */47 void postorderTraversal(struct BTreeNode *root)48 {49     initStack(tempStack, STACKSIZE);           // 初始化元素为结点类型指针的栈tempStack,用以保存刚访问过的结点,利于回溯50     initStack(postStack, BTREESIZE);           // 初始化元素为结点类型指针的栈postStack,用以保存按“根-右-左”顺序依次访问的结点51 52     struct BTreeNode *currentNode = root;                   // currentNode指向当前要访问的结点,初始时指向根结点53     while(currentNode != NULL || !isEmpty(tempStack)) {     /* 当currentNode为空结点其tempStack栈空,遍历结束 */54         if(currentNode != NULL) {                           // 若currentNode指向的不是空结点55             push(postStack, currentNode);                   // currentNode结点压入postStack栈中56             push(tempStack, currentNode);                   // currentNode结点压入tempStack栈中57             currentNode = currentNode->rightChild;          // 使currentNode指向当前结点的右孩子结点58         } else {                                            // 若currentNode不为空结点    59             currentNode = pop(tempStack);                   // 弹出tempStack栈顶结点指针并赋给currentNode指针60             currentNode = currentNode->LChild;              // 是使currentNode指向当前结点的左孩子结点61         }62     }63     outStack(postStack);64 }

层序遍历:

1 /* 2  * 层序遍历二叉树 3  */ 4 void levelOrderTraversal(struct BTreeNode *root) 5 { 6     initQueue(queue, QUEUESIZE);                        // 初始化元素为二叉树结点指针类型的队列 7     if(root != NULL)                                    // 若二叉树不为空,根结点指针入队 8         enQueue(queue, root); 9 10     struct BTreeNode currentNode = NULL;11     while(!isEmpty(queue)) {                            /* 直到队列为空,遍历结束 */12         currentNode = outQueue(queue);                  // 队头元素出列13         print(currentNode->data);                       // 访问当前结点信息14         if(currentNode->LChild != NULL)                /* 若当前结点有左孩子,则将其入队 */15             enQueue(queue, currentNode->LChild);16         if(currentNode->rightChild != NULL)             /* 若当前结点有右孩子,则将其入队 */17             enQueue(queue, currentNode->rightChild);18     }19 }

二叉树遍历方法的简单应用:

1 /* 2  * 前序遍历应用:输出二叉树   递归实现 3  */ 4 void outBTree(struct BTreeNode *root) 5 { 6     if(root != NULL) {                                                  // 若二叉树为空 7         print(root->data);                                              // 输出根结点值 8         if(root->LChild != NULL || root->rightChild != NULL) {         // 有左子树或右子树 9             print("(");                                        // 输出左括号10             outBT(root->LChild);                              // 输出左子树11             print(",");                                        // 输出左右子树的分隔符12             if(root->rightChild != NULL)                       // 若有右子树13                 outBTree(root->rightChild);                    // 输出右子树            14             print(")");                                        // 输出右括号15         }16     }17 }18 19 /*20  * 前序遍历应用:查找二叉树中是否存在指定值   递归实现21  */22 bool findBTree(struct BTreeNode *root, ElementType item)23 {24     if(root == NULL) {                                          // 二叉树为空,则返回false25         return false;26     } else {27         if(root->data == item) {                                // 若根结点为所找结点,返回true28             return true;29         } else {30             if(findBTree(root->LChild, item) == true) {        // 递归查找当前结点的左子树,若找到,返回true31                 return true;32             }33             if(findBTree(root->rightChild, item) == true) {     // 递归查找当前结点的右子树,若找到,返回false34                 return true;35             }36             return false;                                       // 若左右子树都未找到,返回false37         }38     }39 }40 41 /*42  * 后序遍历应用:计算二叉树的深度     递归实现43  */44 int getBTreeDeepth(struct BTreeNode *root)45 {   46     if(root == NULL) {                                                      // 二叉树为空,返回深度为047         return 0;48     } else {49         int deepth_1 = getBTreeDeepth(root->LChild);                       // 递归求左子树的深度50         int deepth_2 = getBTreeDeepth(root->RChild);                       // 递归求右子树的深度51         return (deepth_1 > deepth_2) ? (deepth_1 + 1) : (deepth_2 + 1);     // 求出树的深度并返回52     }53 }54 55 /*56  * 后序遍历应用:清空二叉树   递归实现57  */58 void clearBTree(struct BTreeNode *root)59 {60     /* 若二叉树为空树,则结束递归 */61     if(root != NULL) {62         clearBTree(root->LChild);        // 递归删除根结点的左子树63         clearBTree(root->rightChild);     // 递归删除根结点的右子树64         delete root;                 // 释放根结点65         root = NULL;                // 将根结点指针置空66     }67 }

 

OK哒!

转载于:https://www.cnblogs.com/gotodsp/p/3848751.html

你可能感兴趣的文章
会话控制
查看>>
推荐一款UI设计软件Balsamiq Mockups
查看>>
Linux crontab 命令格式与详细例子
查看>>
百度地图Api进阶教程-地图鼠标左右键操作实例和鼠标样式6.html
查看>>
游标使用
查看>>
LLBL Gen Pro 设计器使用指南
查看>>
SetCapture() & ReleaseCapture() 捕获窗口外的【松开左键事件】: WM_LBUTTONUP
查看>>
Android 设置界面的圆角选项
查看>>
百度地图api服务端根据经纬度得到地址
查看>>
根据xml生成相应的对象类
查看>>
Android StageFrightMediaScanner源码解析
查看>>
打包java程序生成exe
查看>>
八叉树
查看>>
Git 远程仓库
查看>>
关于静态文本框透明度的问题
查看>>
javascript的发展及个人笔记
查看>>
全选,反全选,反选,获取选中的值,根据子选择控制全选按钮
查看>>
[CF#250 Div.2 D]The Child and Zoo(并查集)
查看>>
博客园博客插入公式
查看>>
hdu 1028 Ignatius and the Princess III(母函数入门+模板)
查看>>