二叉树的先中后序遍历
2015-10-21 20:06
375 查看
【0】README
0.1)本文旨在理清二叉树的先中后序遍历, 以及如何建立二叉树等相关内容;0.2)本文涉及代码均为原创;
0.3)本文中遍历后的打印结果,朋友您可以直接写出二叉树的节点构造出来;
Attention):
A1)要建立二叉树或者普通树, 这就涉及到插入节点的问题; 进而涉及到找到插入到哪个父节点的哪个孩子问题(left or right);当然,我们可以抽取一个 find 方法出来找出父节点, find 方法的关键是 首先要对是否为空树进行测试;
A2) 而且,你要知道,在后面的二叉查找树的 插入方法insert 和 我们的 二叉树或者普通树的插入方法是不同的, 因为二叉查找树的定义是 :“该树中的每个节点 X, 它的左子树中所有关键字值 小于 X 的关键字值, 而它的右子树中所有关键字值大于 X 的关键字值”; 换句话说,在二叉查找树中,节点之间是有大小关联的, 而在二叉树和其它普通树中,节点间的数值大小是没有关系的,任意的 (特别要注意);
【1】二叉树相关概念
1.1)定义:二叉树是一颗树,其中每个节点都不能有多余两个儿子;1.2)重要性质:平均二叉树的深度要比N小得多(N是该二叉树的节点个数);
【2】二叉树的表示方法说明:
2.1)树一般画成圆圈并用一些直线连接起来,因为二叉树实际上就是图,但涉及到树时, 我们也不明显地画出 NULL 指针,因为具有N个节点的每一个二叉树都将需要 N+1 个 NULL 指针;2.2)为什么是N+1个NULL 指针? 因为N个节点==2N个指针==N-1条边;故余下N+1条边为 NULL , 即N+1个指针为NULL;(除根节点root外,每个节点都对应一条边)
【3】对二叉树的先序 + 中序 + 后序遍历
Attention)对于二叉树的遍历,我们的简单想法是, 遍历后的结果,我可以画出该二叉树节点的构造;3.1)先序遍历步骤:如果二叉树为空树, 则什么都不做; 否则:
step1)访问根节点;
step2)先序遍历左子树;
step3)先序遍历右子树;
3.1.1)download source code : https://github.com/pacosonTang/dataStructure-algorithmAnalysis/blob/master/chapter4/p70_preorder_binary_tree.c
3.1.2)source code at a glance :
#include <stdio.h> #include <malloc.h> #define ElementType char #define Error(str) printf("\n error: %s \n",str) struct BinaryTree; typedef struct BinaryTree *BinaryTree; BinaryTree createBinaryTree(); BinaryTree makeEmpty(BinaryTree t); BinaryTree insert(ElementType e, BinaryTree t, int); // we adopt child-sibling notation struct BinaryTree { ElementType value; BinaryTree left; BinaryTree right; }; // create a BinaryTree with root node BinaryTree createBinaryTree() { BinaryTree t; t = (BinaryTree)malloc(sizeof(struct BinaryTree)); if(!t) { Error("out of space, from func createBinaryTree"); return NULL; } t->left = NULL; t->right = NULL; t->value = '/'; return t; } // make the BinaryTree empty BinaryTree makeEmpty(BinaryTree t) { if(t){ makeEmpty(t->left); makeEmpty(t->right); free(t); } return NULL; } //insert a Tree node with value e into left child or right child of the parent BinaryTree insert(ElementType e, BinaryTree parent, int isLeft) { BinaryTree node; if(!parent){ Error("for parent BinaryTree node is empty , you cannot insert one into the parent node, from func insert"); return NULL; } node = (BinaryTree)malloc(sizeof(struct BinaryTree)); if(!node) { Error("out of space, from func insert"); return NULL; } node->value = e; node->right = NULL; node->left = NULL;// building the node with value e over if(isLeft) { // the tree node inserting into left child of the parent if(parent->left) { Error("for parent has already had a left child , you cannot insert one into the left child, from func insert"); return NULL; } parent->left = node; } else { // the tree node inserting into right child of the parent if(parent->right) { Error("for parent has already had a right child , you cannot insert one into the right child, from func insert"); return NULL; } parent->right = node; } return node; } // find the BinaryTree root node with value equaling to e BinaryTree find(ElementType e, BinaryTree root) { BinaryTree temp; if(root == NULL) return NULL; if(root->value == e) return root; temp = find(e, root->left); if(temp) return temp; else return find(e, root->right); } // analog print directories and files name in the BinaryTree, which involves postorder traversal. void printPreorder(int depth, BinaryTree root) { int i; if(root) { for(i = 0; i < depth; i++) printf(" "); printf("%c\n", root->value); printPreorder(depth + 1, root->left); printPreorder(depth + 1, root->right); // Attention: there's difference between traversing binary tree and common tree } else { for(i = 0; i < depth; i++) printf(" "); printf("NULL\n"); } } int main() { BinaryTree BinaryTree; BinaryTree = createBinaryTree(); printf("\n ====== test for postordering the BinaryTree presented by left_right_child structure ====== \n"); printf("\n test for respectively inserting 'A' and 'B' into left and right child of the parent '/' , then 'C' and 'D' into the left and right child of the parent 'A' \n"); insert('A', find('/', BinaryTree), 1); // 1 means left child insert('B', find('/', BinaryTree), 0); // 0 means right child insert('C', find('A', BinaryTree), 1); insert('D', find('A', BinaryTree), 0); printPreorder(1, BinaryTree); printf("\n test for respectively inserting 'A' and 'B' into left and right child of the parent '/' \n"); insert('E', find('/', BinaryTree), 1); insert('F', find('/', BinaryTree), 0); printPreorder(1, BinaryTree); printf("\n test for inserting 'E' into the right child of the parent 'B' , then repectively 'F' and 'G' into the left and right child of the parent 'H' \n"); insert('E', find('B', BinaryTree), 0); insert('F', find('E', BinaryTree), 1); insert('G', find('E', BinaryTree), 0); printPreorder(1, BinaryTree); /**/ return 0; }
3.2)中序遍历步骤:如果二叉树为空树, 则什么都不做; 否则:
step1)中序遍历左子树;
step2)访问根节点;
step3)中序遍历右子树;
3.2.1)download source code : https://github.com/pacosonTang/dataStructure-algorithmAnalysis/blob/master/chapter4/p70_inorder_binary_tree.c
3.2.2)source code at a glance :(Attention:要知道前序+中序+后序遍历的源代码的唯一不同是 打印函数的不同,这里,我们只给出中序的打印函数,其他的函数同前序是一样的,这里不再重复给出, 同时我们的后序遍历代码也只是给出了打印函数,其他函数同前序遍历一样,下文不再累述)
// analog print directories and files name in the BinaryTree, which involves postorder traversal. void printInorder(int depth, BinaryTree root) { int i; if(root) { printInorder(depth + 1, root->left); for(i = 0; i < depth; i++) printf(" "); printf("%c\n", root->value); printInorder(depth + 1, root->right); // Attention: there's difference between traversing binary tree and common tree } else { for(i = 0; i < depth; i++) printf(" "); printf("NULL\n"); } }
3.3)后序遍历步骤:如果二叉树为空树, 则什么都不做; 否则:
step1) 后序遍历左子树;
step2) 后序遍历右子树;
step3) 访问根节点;
3.3.1)download source code: https://github.com/pacosonTang/dataStructure-algorithmAnalysis/blob/master/chapter4/p70_postorder_binary_tree.c
3.3.2)source code at a glance:
// analog print directories and files name in the BinaryTree, which involves postorder traversal. void printPostorder(int depth, BinaryTree root) { int i; if(root) { printPostorder(depth + 1, root->left); printPostorder(depth + 1, root->right); // Attention: there's difference between traversing binary tree and common tree for(i = 0; i < depth; i++) printf(" "); printf("%c\n", root->value); } else { for(i = 0; i < depth; i++) printf(" "); printf("NULL\n"); } }
相关文章推荐
- AVL树-自平衡二叉查找树(Java实现)
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构揭秘一
- 数据结构之Treap详解
- C语言二叉树的非递归遍历实例分析
- 使用C语言构建基本的二叉树数据结构
- C++非递归队列实现二叉树的广度优先遍历
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)
- java数据结构和算法学习之汉诺塔示例