学了几章的数据结构,我发现每一章对结构的阐述都会有以下三个步骤:
1.先定义数据结构和基本操作。就是所谓的抽象,把像的总体特征抽出来,有的也会去归纳出结构的性质。
2.数据结构的存储,一般分为顺序存储结构和链式存储结构。
3.根据存储结构来建立数据结构和给出实现各种操作的算法。
同样对二叉树的总结,我也用这种方法来组织吧。
1.二叉树的定义
(1)每个结点的度都不大于2;
(2)每个结点的孩子结点次序不能任意颠倒;
2.二叉树的存储结构
(1)顺序存储结构
将二叉树中编号为i的结点存放在数组的第i个分量中,可得结点i的左孩子位置为2*i;右孩子的位置为2*i+1。
优点:对于完全二叉树来说非常方便。
缺点:对于一般二叉树,必须用“虚结点”将其补成一颗“完全二叉树”来存储,由于编号为i的结点存放在i分量中,这就导致“虚结点”空间的浪费。
(2)链式存储结构
因为对于二叉树来说,每个结点都有左右孩子结点和双亲结点。可以设计每个结点包括三个域:数据域,左孩子域,右孩子域。分别存放结点数据,指向左孩子结点的指针,指向右孩子结点的指针。这样在建立二叉树时用递归方法,先建立根结点,再建立全部的左子树,后建立全部右子树。这时候在运行输入时也要按照建立的形式去输入,看是先序遍历建立还是其他的。(下面建立二叉树时讲)。
typedef struct Node
{
DataType data;
struct Node *LChild;
struct Node *RChild;
}BiTNode, *BiTree;
3.二叉树的基本操作
先讲二叉树的遍历,再由遍历来引出二叉树的建立,因为二叉树也是利用递归遍历的形式来建立的。
(1)按照先左后右的的顺序分为三种:
先序遍历
void PreOrder(BiTree root)
/*先序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/
{
if (root!=NULL)
{
Visit(root ->data); /*访问根结点*/
PreOrder(root ->LChild); /*先序遍历左子树*/
PreOrder(root ->RChild); /*先序遍历右子树*/
}
}
中序遍历
void InOrder(BiTree root)
/*中序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/
{
if (root!=NULL)
{
InOrder(root ->LChild); /*中序遍历左子树*/
Visit(root ->data); /*访问根结点*/
InOrder(root ->RChild); /*中序遍历右子树*/
}
}
后续遍历
void PostOrder(BiTree root)
/* 后序遍历二叉树,root为指向二叉树(或某一子树)根结点的指针*/
{
if(root!=NULL)
{
PostOrder(root ->LChild); /*后序遍历左子树*/
PostOrder(root ->RChild); /*后序遍历右子树*/
Visit(root ->data); /*访问根结点*/
}
}
(2)建立二叉树
#include <stdio.h>
#include <malloc.h>
#include <conio.h>
typedef char DataType;
typedef struct Node
{
DataType data;
struct Node *LChild;
struct Node *RChild;
}BiTNode, *BiTree;
void CreateBiTree(BiTree *bt)
{
char ch;
ch = getchar();
if(ch=='.') *bt=NULL;
else
{
*bt=(BiTree)malloc(sizeof(BiTNode)); //生成一个新结点
(*bt)->data=ch;
CreateBiTree(&((*bt)->LChild)); //生成左子树
CreateBiTree(&((*bt)->RChild)); //生成右子树
}
}
按照上述代码建立二叉树,如建立下图这样的二叉树,用户输入的格式应该是ABD.G...CE..F..【enter】。
(3)二叉树遍历的应用
需求:遍历二叉树并把每个结点的值和层数打印出来。
代码如下:
#include "bitTree.h"
void visit(DataType data,int layer)
{
printf("%c.....第%d层\n",data,layer);
}
void printLayer(BiTree T,int layer)
{
if(T!=NULL)
{
visit(T->data,layer);
printLayer(T->LChild,layer+1);
printLayer(T->RChild,layer+1);
}
}
void main()
{
BiTree T;
int layer=1;
printf("请输入二叉树:\n");h
CreateBiTree(&T);
printLayer(T,layer);
}
运行结果为: