树和二叉树

早在很久之前,就听过什么树,二叉树,当时觉得似乎是什么很高端的东西,不过这章学完之后发现,原来树是我们平时很常用很普遍的一种层次数据结构而已。因为树和森林都能化为二叉树,所以总结二叉树的常见操作。

1:二叉树节点的建立

typedef  struct BiTNode
{
    ElemType data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

    

2:二叉树的遍历

先序遍历

中序遍历

后序遍历

这三种遍历主要就是访问节点数据与访问节点左右孩子的顺序区别,本质没什么区别

还有层序遍历

设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。
 
通过已创建的节点与遍历算法就可以实现二叉树的建立了。
 
下面是代码

#include<iostream>
#include<stdlib.h>
using namespace std;

typedef char ElemType;

//二叉树的二叉链表结构,也就是二叉树的存储结构,1个数据域,2个指针域(分别指向左右孩子)

typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

//二叉树的建立,按前序遍历的方式建立二叉树,当然也可以以中序或后序的方式建立二叉树
void CreateBiTree(BiTree *T)
{
ElemType ch;
cin >> ch;
if (ch == '#')
*T = NULL; //保证是叶结点
else
{
*T = (BiTree)malloc(sizeof(BiTNode));
//if (!*T)
//exit(OVERFLOW); //内存分配失败则退出。
(*T)->data = ch;//生成结点
CreateBiTree(&(*T)->lchild);//构造左子树
CreateBiTree(&(*T)->rchild);//构造右子树
}
}
//表示对遍历到的结点数据进行的处理操作,此处操作是将树结点前序遍历输出
void operation1(ElemType ch)
{
cout << ch << " ";
}
//此处在输出的基础上,并输出层数
void operation2(ElemType ch, int level)
{
cout << ch << "在第" << level << "层" << endl;
}


//递归方式前序遍历二叉树
void PreOrderTraverse(BiTree T, int level)
{
if (T == NULL)
return;
/*此处表示对遍历的树结点进行的操作,根据你自己的要求进行操作,这里只是输出了结点的数据*/
//operation1(T->data);
operation2(T->data, level); //输出了层数

PreOrderTraverse(T->lchild, level + 1);
PreOrderTraverse(T->rchild, level + 1);
}

//递归方式中序遍历二叉树

void InOrderTraverse(BiTree T, int level)
{
if (T == NULL)
return;
InOrderTraverse(T->lchild, level + 1);

//operation1(T->data);
operation2(T->data, level); //输出了层数

InOrderTraverse(T->rchild, level + 1);
}

//递归方式后序遍历二叉树

void PostOrderTraverse(BiTree T, int level)
{
if (T == NULL)
return;
PostOrderTraverse(T->lchild, level + 1);
PostOrderTraverse(T->rchild, level + 1);

//operation1(T->data);
operation2(T->data, level); //输出了层数
}


int main()
{
int level = 1; //表示层数
BiTree T = NULL;
cout << "请以前序遍历的方式输入扩展二叉树:"; //类似输入AB#D##C##
CreateBiTree(&T);// 建立二叉树,没有树,怎么遍历

cout << "递归前序遍历输出为:" << endl;
PreOrderTraverse(T, level);//进行前序遍历,其中operation1()和operation2()函数表示对遍历的结点数据进行的处理操作
cout << endl;

cout << "递归中序遍历输出为:" << endl;
InOrderTraverse(T, level);
cout << endl;

cout << "递归后序遍历输出为:" << endl;
PostOrderTraverse(T, level);
cout << endl;

return 0;
}

 

关于二叉树有很多应用,其中计算机因为采用二进制所以通过构造哈夫曼树可以寻找到带权路径往往就是最优解。如文字编码问题

 

总的来说这章我的学习很多都是停留在对概念,对算法的理解上,实际的打代码还是太少了,所以现在造成了有思路,听得懂,但是一打就出错,所以今后的学习还是要多打,像这次作业的树的同构,还有输出所有叶子的那题,都没能凭借自己的力量完成,要加油了啊......