昨天才写了篇关于二叉排序树的博客,想起之前有所遗漏,如先序,中序以及后序遍历;
先序遍历:也叫做先根遍历,前序遍历,可记做根左右(二叉树父结点向下先左后右)。首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树,如果二叉树为空则返回。
即:若二叉树为空则结束返回,否则:(1)访问根结点(2)先序遍历左子树(3)先序遍历右子树
中序遍历:首先遍历左子树,然后访问根结点,最后遍历右子树。在遍历左、右子树时,仍然先遍历左子树,再访问根结点,最后遍历右子树。
即:若二叉树为空则结束返回,否则:(1)中序遍历左子树(2)访问根结点(3)中序遍历右子树
后序遍历:首先遍历左子树,然后遍历右子树,最后遍历访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。
即:若二叉树为空则结束返回,否则:(1)后序遍历左子树(2)后序遍历右子树(3)访问根结点
主要思想如上所述,将上篇二叉搜索树修改如下(当然其中的查找等操作已删除):
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef int ElemType;
typedef struct Node
{
ElemType key; //关键字
struct Node *left; //左孩子
struct Node *right; //右孩子
struct Node *parent; //父节点
} Node, *PNode;
//插入
void Insert(PNode &root, ElemType key)
{
//初始化b被插入结点
PNode p=(PNode)malloc(sizeof(Node));
p->key = key;
p->left = NULL;
p->right = NULL;
p->parent = NULL;
//空树
if(root == NULL)
{
root = p;
return;
}
//左孩子
if(root->left == NULL && root->key > key)
{
p->parent = root;
root->left = p;
return;
}
//右孩子
if(root->right == NULL && root->key < key)
{
p->parent = root;
root->right = p;
return;
}
//关键值小于此时的节点值,放在左树
//准备改回迭代的,今晚没成功...
if(key < root->key)
Insert(root->left,key);
else
Insert(root->right,key);
}
//创建树
void Create(PNode& root, ElemType *keyArray, int length)
{
for(int i = 0; i < length; i++)
Insert(root, keyArray[i]); //插入
}
void PreOrder(PNode root) //先序遍历
{
if(root != NULL)
{
cout<<root->key<<" ";
PreOrder(root->left);
PreOrder(root->right);
}
}
void InOrder(PNode root) //中序遍历
{
if(root != NULL)
{
InOrder(root->left);
cout<<root->key<<" ";
InOrder(root->right);
}
}
void PostOrder(PNode root) //后序遍历
{
if(root != NULL)
{
PostOrder(root->left);
PostOrder(root->right);
cout<<root->key<<" ";
}
}
int main()
{
PNode root = NULL;
ElemType nodeArray[11] = {15, 6, 18, 3, 7, 17, 20, 2, 4, 13, 9}; //二叉数
Create(root, nodeArray, 11); //创建二叉搜索数
cout<<"先序遍历:";
PreOrder(root);
cout<<endl;
cout<<"中序遍历:";
InOrder(root);
cout<<endl;
cout<<"后序遍历:";
PostOrder(root);
cout<<endl;
return 0;
}
建树如下:
遍历情况如下:
o(∩_∩)o