1、顺序存储结构
//------二叉树的顺序存储表示-----------
#define MAX_TREE_SIZE 100 //二叉树的最大结点数
typedef TElemType SqBiTree[MAX_TREE_SIZE]; // 0 号单元存储根结点
SqBiTree bt; //
6.6中的(a)顺序存储结构 对应 b
6.6中的(b)顺序存储结构 对应 c
(由此可见:这种顺序存储结构仅适用于完全二叉树,因为在最坏的情况下,一个深度为k且只用k个结点的单支树却需要长度为2^k-1 的一维数组)
2、链式存储结构
二叉树的结点(如图6.7(a)所示)由一个数据元素和分别指向其左、右子树的两个分支构成,则表示二叉树的链表中 的结点至少包含3个域:数据域和左、右指针域。
有时,为了便于找到结点的双亲,则可以在结点结构中增加一个指向其双亲结点的指针域,(如图6.7(c)所示)
利用这两种结构所得二叉树的存储结构分别称之为 二叉链表 和 三叉链表。
如图6.8所示:链表的头指针指向二叉树的根结点。容易证得,在含有 n 个结点的二叉链表中有 n+1个空链域。
//-----------二叉树的二叉链表存储表示--------
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;
//-----------基本操作的函数原型说明---------
Status CreateBiTree(BiTree &T);
//按先序次序输入二叉树中结点的值,空格字符表示空树
//构造二叉树链表表示的二叉树T
Status PreOrderTraverse(BiTree T,Status (*Visit)(TElemType e));
//采用二叉树的存储结构,Visit 是对结点操作的应用函数
//先序遍历
Status InOrderTraverse(BiTree T,Status (*Visit)(TElemType e));
//采用二叉树的存储结构,Visit 是对结点操作的应用函数
//中遍历
Status PostOrderTraverse(BiTree T,Status (*Visit)(TElemType e));
//采用二叉树的存储结构,Visit 是对结点操作的应用函数
//后序遍历
Status LevelOrderTraverse(BiTree T,Status (*Visit)(TElemType e));
//采用二叉树的存储结构,Visit 是对结点操作的应用函数
//层次遍历
--------------------------------------------------------------------------------------------------------------------------------
代码部分:(二叉树的二叉链表存储的方法)
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
//宏定义
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define YES 1
#define NO 0
#define STACK_INIT_SIZE 100 //栈存储空间初始分配量
#define STACKINCREMENT 10 //栈存储空间分配增量
#define MAXSIZE 40
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef char AtomType; /* 定义原子类型为字符型 */
typedef char TElemType; // 定义原子类型为字符型
//-----------二叉树的二叉链表存储表示--------
//-----------基本操作的函数原型说明---------
//Status CreateBiTree(BiTree &T);
//按先序次序输入二叉树中结点的值,空格字符表示空树
//构造二叉树链表表示的二叉树T
//Status PreOrderTraverse(BiTree T,Status (*Visit)(TElemType e));
//采用二叉树的存储结构,Visit 是对结点操作的应用函数
//先序遍历
//Status InOrderTraverse(BiTree T,Status (*Visit)(TElemType e));
//采用二叉树的存储结构,Visit 是对结点操作的应用函数
//中遍历
//Status PostOrderTraverse(BiTree T,Status (*Visit)(TElemType e));
//采用二叉树的存储结构,Visit 是对结点操作的应用函数
//后序遍历
//Status LevelOrderTraverse(BiTree T,Status (*Visit)(TElemType e));
//采用二叉树的存储结构,Visit 是对结点操作的应用函数
//层次遍历
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;
typedef BiTree SElemType;
//栈的顺序结构体
typedef struct{
SElemType *base; //在栈构造之前和销毁之后,base 的值为NULL;
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间,以元素为单位
}SqStack;
typedef BiTree QElemType;
//队列的结构体
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
typedef QueuePtr SQElemType;
//1.构造一个空队列Q
Status InitQueue(LinkQueue *Q){
//构造一个空队列Q
Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q->front) exit(OVERFLOW); //存储分配失败
Q->front->next=NULL;
return OK;
}
//2.若队列Q为空队列,则返回TRUE,否则返回FALSE
Status QueueEmpty(LinkQueue Q){
if(Q.front->next==NULL)
return TRUE;
else
return FALSE;
}
//3、队列是否为空
Status IsQueueEmpty(LinkQueue *q)
{
if (q->front)
{
return false;
}
else
{
return true;
}
}
//3.插入元素e为Q的新的队尾元素
Status EnQueue(LinkQueue *Q,SQElemType e){
if(IsQueueEmpty(Q)){
Q->front=e;
Q->rear=e;
}
else{
Q->rear->next=e;
Q->rear=e;
}
return OK;
}
//4. 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回 ERROR
Status DeQueue(LinkQueue *q, QNode **p)
{
*p = q->front;
if (q->front == q->rear) //只有1个节点
{
q->front = NULL;
q->rear = NULL;
}
else
{
q->front = q->front->next;
}
return OK;
}
//1.初始化栈
Status InitStack(SqStack &S){
//构造一个空栈S
S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(! S.base) exit(OVERFLOW); //存储分配失败
S.top=S.base; //当栈为空时,栈底等于栈顶
S.stacksize=STACK_INIT_SIZE; //栈可存储的个数
return OK;
}
//2、入栈
Status Push(SqStack &S,SElemType e)
{ //插入元素 e 为新的栈顶元素
if(S.top-S.base >= STACK_INIT_SIZE) //栈满的时候就需要追加存储空间
{
S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base) exit(OVERFLOW); //存储空间分配失败
S.top=S.base+S.stacksize; //栈底的位置可能改变,需要重新定位栈顶元素
//S.top 还是之前的那个没有存储的位置
S.stacksize = S.stacksize+STACKINCREMENT;
}
*S.top=e;
S.top++;
return OK;
}
//3.栈顶出栈元素
Status Pop(SqStack &S,SElemType &e){
//若栈不为空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK ,否则返回ERROR
if(S.top == S.base) return ERROR;
e=*(--S.top); //可以不加括号,但需要记住的是,需要让 top 指针减 1 ,再取出元素
return OK;
}
//4.判断栈是否为空
Status StackEmpty( SqStack S)
{
if(S.top==S.base)
return YES;
else
return NO;
}
//6.求栈顶元素
Status GetTop(SqStack S,SElemType e)
{
if(S.top==S.base)
return FALSE;
else
e=*(S.top-1);
return OK;
}
//按先序次序输入二叉树中结点的值,'#'字符表示空树,构造二叉树链表表示的二叉树T
Status CreateBiTree(BiTree &T){
char ch;
scanf("%c", &ch);
if(ch=='#')
T=NULL;
else{
if(!(T=(BiTree)malloc(sizeof(BiTNode))))
exit(OVERFLOW);
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //构造左子树
CreateBiTree(T->rchild); //构造右子树
}
return OK;
}
//采用二叉树的存储结构,Visit 是对结点操作的应用函数,先序遍历
Status PreOrderTraverse(BiTree T,Status (*visit)(TElemType e)){
if(T){
if(visit(T->data))
if(PreOrderTraverse(T->lchild,visit))
if(PreOrderTraverse(T->rchild,visit))
return OK;
return ERROR;
}
else
return OK;
}
//采用二叉树的存储结构,Visit 是对结点操作的应用函数,中序遍历
Status InOrderTraverse(BiTree T, Status (*Visit)(TElemType e))
{
SqStack S;
InitStack(S);
BiTree p = T;
while( p || !StackEmpty(S) )
{
if(p)
{
Push(S,p);
p = p->lchild; //根指针进栈,遍历左子树
}
else
{ //根指针退栈,访问根结点,遍历右子树
Pop(S,p);
if(!Visit(p->data))
return ERROR;
p = p->rchild;
}
}
return OK;
}
/*
//采用二叉树的存储结构,Visit 是对结点操作的应用函数,中序遍历
Status InOrderTraverse(BiTree T,Status (*visit)(TElemType e)){
SqStack S;
InitStack(S);
BiTree p=T;
Push(S,T); //根指针进栈
while(!StackEmpty(S)){
while(GetTop(S,p) && p!=NULL)
Push(S,p->lchild); //向左走到尽头 //这一句会一直重复
Pop(S,p); //空指针退栈
if(!StackEmpty(S)){ //访问结点,向右一步
Pop(S,p);
if(!visit(p->data)){
return ERROR; printf("have error!"); }
Push(S,p->rchild);
}
}
return OK;
}
*/
/*
Status InOrderTraverse (BiTree T, Status (* visit)(TElemType e))
{
if (T)
{
InOrderTraverse(T->lchild, visit);
visit(T->data);
InOrderTraverse(T->rchild, visit);
}
return OK;
} */
//采用二叉树的存储结构,Visit 是对结点操作的应用函数,后序遍历
Status PostOrderTraverse(BiTree T, Status (* Visit)(TElemType e))
{
if (T)
{
PostOrderTraverse(T->lchild, Visit);
PostOrderTraverse(T->rchild, Visit);
Visit(T->data);
}
return OK;
}
//采用二叉树的存储结构,Visit 是对结点操作的应用函数,层次遍历
Status LevelOrderTraverse(BiTree T){ //由于时间关系,在此的层次存储结构还未完全设计好,可自行解决
if(!T){
return ERROR;
}
LinkQueue m_queue;
LinkQueue *Q;
QNode *p,*q;
Q = &m_queue;
InitQueue(Q); //队列初始化
p=(QueuePtr)malloc(sizeof(QNode));
p->next=NULL;
p->data=T;
EnQueue(Q,p); //根结点入队
while(!IsQueueEmpty(Q)){
DeQueue(Q, &q); //当前队首节点出队
printf("%c ",q->data->data);
if(q->data->lchild){ //左孩子非空,则左孩子入队 //q->data->lchild CXX0030: Error: expression cannot be evaluated
p=(QueuePtr)malloc(sizeof(QNode));
p->next=NULL;
p->data=q->data->lchild;
EnQueue(Q,p);
}
if(q->data->rchild){ //右孩子非空,则右孩子入队
p=(QueuePtr)malloc(sizeof(QNode));
p->next=NULL;
p->data=q->data->rchild;
EnQueue(Q,p);
}
}
return OK;
}
Status visit(TElemType e){
printf("%c",e);
return OK;
}
void main(){
BiTree T;
CreateBiTree(T);
printf("\nPre: ");
PreOrderTraverse(T,visit);
printf("\nIn: ");
InOrderTraverse(T,visit);
printf("\nPost: ");
PostOrderTraverse(T, visit);
printf("\n");
printf("\nLevel: ");
LevelOrderTraverse(T);
printf("\n");
}
代码的运行结果: