您的位置:首页 > 理论基础 > 数据结构算法

二叉树的先中后序遍历

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");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树 数据结构