赞
踩
对于完全二叉树而言,我们用一组地址连续的存储单元即一维数组依次从上至下从左至右的存储该完全二叉树 中的节点元素,对于普通的二叉树我们将其结点与其对应的完全二叉树相对照,存储在一维数组中,例如:
二叉树的顺序存储的特点
说明:鉴于顺序存储的二叉树比较简单,读者可以自己尝试定义二叉树的结点,然后将结点存储在一维数组中即可。
二叉树的结点可以用结构体类型来表示,定义不同的结点结构,可以构成不同的链式存储结构。
二叉链表:存储该二叉树的链表的结点的指针域有两个,分别指向该节点的左右孩子结点
三叉链表: 存储该二叉树的链表的结点的指针域有三个,分别指向左孩子结点,双亲结点,以及右孩子结点
由以上定义可知对二叉树的三种遍历方法都是递归的所以设计遍历方法时需要用到递归
下面演示用二叉链表来表示如图所示的二叉树,以及采用三种遍历方法遍历该二叉树的过程,在程序代码中给出了完整的注释:
- typedef struct BitNode
- {
- char value; //数据域,用于存放该节点的值
- struct BitNode* lchild, * rchild; //二叉链表的节点中有两个指针与分别指向该节点的左右孩子节点
-
-
- }BitNode,*Bitree; //为定义的结构体类型起别名为BitNode,以及为该结构体类型的指针起别名为Bitree,此时执行语句"BitNode a"相当于执行语句"struct BitNode a",执行语句"Bitree a"相当于执行语句"BitNode *a"
第二步创建该二叉树
- Bitree CreateTree(Bitree head)
- {
- char value;
- Bitree p;
- //p = head = NULL; //相当于每次调用该函数都会把头指针设置为空指针;这显然是错误的
-
- printf("请输入节点的值\n");
- scanf("%c", &value);
- getchar();
-
- if (value == '#')
- return NULL; //创建二叉树,当输入#号时表示不再继续输入返回空指针给上一级调用对象,即将上一级节点没有左孩子或者没有右孩子,理解这一点很重要,函数的返回值是所定义的结构体类型的指针
- else
- {
-
- p = (Bitree)malloc(sizeof(BitNode));
- p->value = value;
- if (!head)
- head = p; //创建头指针;
-
- printf("请输入%c的左子树的根节点\n", value);
- p->lchild = CreateTree(head); //递归创建左子树;
- printf("请输入%c的右子树的根节点\n", value);
- p->rchild = CreateTree(head); //递归创建右子树;
-
- return p; //函数出口返回的是指向创建的二叉树的第一个结点的指针;
-
- }
- }

先序遍历该二叉树
- void FirstOrderTraverse(Bitree p)
- {
- if (p == NULL)
- return;
- printf("%c\t", p->value);
- FirstOrderTraverse(p->lchild);
- FirstOrderTraverse(p->rchild);
-
-
- }
中序遍历该二叉树
- void MiddleOrderTraverse(Bitree p)
- {
- if (p == NULL)
- return;
- MiddleOrderTraverse(p->lchild);
- printf("%c\t", p->value);
- MiddleOrderTraverse(p->rchild);
-
-
- }
后序遍历该二叉树
- void PostOrderTraverse(Bitree p) //后序遍历二叉树即最后访问根节点
- {
- if (p == NULL)
- return;
-
- PostOrderTraverse(p->lchild); //此递归函数都没有递归结束条件,怎么从递归中出来呢?递归结束条件怎么能不写
- PostOrderTraverse(p->rchild);
- printf("%c\t", p->value);
- }
-
-
程序完整代码以及运行结果截图:
代码:
- //二叉树的定义与储存,用二叉链表存储二叉树
-
-
- #define _CRT_SECURE_NO_WARNINGS
- #include<stdio.h>
- #include<stdlib.h> //该头文件包含了malloc函数的声明;
-
- //定义二叉树的节点结构,采用二叉链表存储该二叉树
- typedef struct BitNode
- {
- char value; //数据域,用于存放该节点的值
- struct BitNode* lchild, * rchild; //二叉链表的节点中有两个指针与分别指向该节点的左右孩子节点
-
-
- }BitNode, * Bitree;//为定义的结构体类型起别名为BitNode,
- //以及为该结构体类型的指针起别名为Bitree,此时执行语句"BitNode a"相当于执行语句"struct BitNode a",执行语句"Bitree a"相当于执行语句"BitNode *a"
-
-
- //创建一棵不带头节点的二叉树的函数
- Bitree CreateTree(Bitree head);
- //后序遍历一棵树
- void FirstOrderTraverse(Bitree p);
- void MiddleOrderTraverse(Bitree p);
- void PostOrderTraverse(Bitree p);
-
-
-
- int main()
- {
- Bitree head = NULL,p;
- head = CreateTree(head);
- if (head)
- printf("树创建成功\n");
- else
- printf("树创建失败\n\n\n");
-
- printf("先序遍历该树的结果\n");
- FirstOrderTraverse(head);
- printf("\n");
-
- printf("中序遍历该树的结果\n");
- MiddleOrderTraverse(head);
- printf("\n");
-
- printf("后序遍历该树的结果\n");
- PostOrderTraverse(head);
- printf("\n");
-
-
- return 0;
-
- }
-
- //函数实现,按照中序遍历的思想创建该二叉树,即先创建根节点再创建根节点的左子树和右子树,根据此思想创建二叉树可以用到递归算法
- Bitree CreateTree(Bitree head)
- {
- char value;
- Bitree p;
- //p = head = NULL; //相当于每次调用该函数都会把头指针设置为空指针;这显然是错误的
-
- printf("请输入节点的值\n");
- scanf("%c", &value);
- getchar();
-
- if (value == '#')
- return NULL; //创建二叉树,当输入#号时表示不再继续输入返回空指针给上一级调用对象,即将上一级节点没有左孩子或者没有右孩子,理解这一点很重要,函数的返回值是所定义的结构体类型的指针
- else
- {
-
- p = (Bitree)malloc(sizeof(BitNode));
- p->value = value;
- if (!head)
- head = p; //创建头指针;
-
- printf("请输入%c的左子树的根节点\n", value);
- p->lchild = CreateTree(head); //递归创建左子树;
- printf("请输入%c的右子树的根节点\n", value);
- p->rchild = CreateTree(head); //递归创建右子树;
-
- return p; //函数出口返回的是指向创建的二叉树的第一个结点的指针;
-
- }
- }
-
-
- void FirstOrderTraverse(Bitree p)
- {
- if (p == NULL)
- return;
- printf("%c\t", p->value);
- FirstOrderTraverse(p->lchild);
- FirstOrderTraverse(p->rchild);
-
-
- }
-
-
- void MiddleOrderTraverse(Bitree p)
- {
- if (p == NULL)
- return;
- MiddleOrderTraverse(p->lchild);
- printf("%c\t", p->value);
- MiddleOrderTraverse(p->rchild);
-
-
- }
-
-
-
-
- void PostOrderTraverse(Bitree p) //后序遍历二叉树即最后访问根节点
- {
- if (p == NULL)
- return;
-
- PostOrderTraverse(p->lchild); //此递归函数都没有递归结束条件,怎么从递归中出来呢?递归结束条件怎么能不写
- PostOrderTraverse(p->rchild);
- printf("%c\t", p->value);
- }
-
-

运行结果截图
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。