欢迎光临散文网 会员登陆 & 注册

《数据结构(C语言版)》二叉树的实现

2022-04-15 15:11 作者:回到唐朝当少爷  | 我要投稿

清华大学计算机系列教材   累计发行超400万册

严蔚敏 吴伟民 编著

数据结构(C语言版) 

以下是本人对该紫皮书第六章树和二叉树中二叉树代码实现,按递归方式先序和后序遍历了二叉树,用非递归的栈实现了中序遍历,用队列实现了层次遍历,并且额外补充了二叉树的复制、计算二叉树的深度、计算二叉树结点总数、计算二叉树叶子结点总数等算法

话不多说上运行结果

(貌似专栏把我缩进吃了,懒得加了,另外建议用visual studio编译,会帮你自动调整缩进)  

代码如下

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

#include <stdlib.h>

#define TRUE 1

#define FALSE 0

#define OK 1

#define ERROR 0

#define INFEASIBLE -1

#define OVERFLOW -2


typedef int Status;

typedef char TElemType;

typedef struct BiTNode

{

TElemType data;

struct BiTNode* lchild, * rchild;

}BiTNode, * BiTree;

typedef BiTNode* SElemType;


/*用栈实现非递归的遍历二叉树算法*/

#define STACK_INIT_SIZE 100//存储空间初始分配量

#define STACKINCREMENT 10//存储空间分配增量

typedef struct

{

SElemType* base;

SElemType* top;

int stacksize;//当前已分配的存储空间,以元素为单位

}SqStack;//用栈实现树的非递归遍历

Status InitStack(SqStack& S);//初始化一个空栈

Status StackEmpty(SqStack S);//判断栈是否为空

Status Push(SqStack& S, SElemType e);//顺序栈的入栈

Status Pop(SqStack& S, SElemType& e);//顺序栈的出栈


/*用队列实现二叉树的层次遍历算法*/

typedef BiTNode* QElemType;

typedef struct QNode

{

QElemType data;

struct QNode* next;

}QNode, * QueuePtr;

typedef struct

{

QueuePtr front;//队头指针

QueuePtr rear;//队尾指针

}LinkQueue;

Status InitQueue(LinkQueue& Q);//链队列的初始化

Status EnQueue(LinkQueue& Q, QElemType e);//入队

Status DeQueue(LinkQueue& Q, QElemType& e);//出队

Status QueueEmpty(LinkQueue Q);//队列是否为空


Status CreatBiTree(BiTree& T);//按先序遍历序列建立二叉树的二叉链表

Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType e));//递归方式实现前序遍历

Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType e));//用非递归方式--栈实现中序遍历

Status PostOrderTraverse(BiTree T, Status(*Visit)(TElemType e));//递归方式实现后序遍历

Status LevelOrderTraverse(BiTree T, Status(*Visit)(TElemType));//用队列实现二叉树层次遍历

Status PrintElement(TElemType e);//打印二叉树元素

Status CopyBiTree(BiTree T, BiTree& NewT);//复制二叉树

int Depth(BiTree T);//计算树的深度

int NodeCount(BiTree T);//计算二叉树结点总数

int LeafCount(BiTree T);//计算二叉树叶子结点总数


int main()

{

BiTree T, Same_T;

CreatBiTree(T);

printf("前序遍历结果为:");

PreOrderTraverse(T, PrintElement);

printf("\n中序遍历结果为:");

InOrderTraverse(T, PrintElement);

printf("\n后序遍历结果为:");

PostOrderTraverse(T, PrintElement);

CopyBiTree(T, Same_T);

printf("\n复制后的树按前序遍历后的结果为:");

PreOrderTraverse(Same_T, PrintElement);

printf("\n树的深度为:%d", Depth(T));

printf("\n树的结点总数为:%d", NodeCount(T));

printf("\n数的叶子结点总数为:%d", LeafCount(T));

return 0;

}

Status CreatBiTree(BiTree& T)//按先序遍历序列建立二叉树的二叉链表

{

char ch;

scanf("%c", &ch);

if (ch == '#')

{

T = NULL;

}

else

{

if (!(T = (BiTNode*)malloc(sizeof(BiTNode))))

{

exit(OVERFLOW);

}

T->data = ch;

CreatBiTree(T->lchild);

CreatBiTree(T->rchild);

}

return OK;

}

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;

}

}

Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//用非递归方式--栈实现中序遍历

{

SqStack S;

InitStack(S);

BiTNode* p = T;

BiTNode* q = NULL;

while (p || !StackEmpty(S))

{

if (p)//如果是根节点

{

Push(S, p);//先入栈

p = p->lchild;//访问它的左子树

}

else//如果左子树为空

{

Pop(S, q);

Visit(q->data);

p = q->rchild;

}

}

return OK;

}

Status PostOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//递归方式实现后序遍历

{

if (T)

{

if (PostOrderTraverse(T->lchild, Visit))

{

if (PostOrderTraverse(T->rchild, Visit))

{

if (Visit(T->data))

{

return OK;

}

return ERROR;

}

}

}

else

{

return OK;

}

}

Status LevelOrderTraverse(BiTree T, Status(*Visit)(TElemType))//用队列实现二叉树层次遍历

{

BiTNode* p;

LinkQueue qu;

InitQueue(qu);

EnQueue(qu, T);

while (!QueueEmpty(qu))

{

DeQueue(qu, p);

Visit(p->data);

if (p->lchild)//有左孩子则进队

{

EnQueue(qu, p->lchild);

}

if (p->rchild)//有右孩子则进队

{

EnQueue(qu, p->rchild);

}

}

return OK;

}

Status PrintElement(TElemType e)//打印二叉树元素

{

printf("%c ", e);

return OK;

}

Status CopyBiTree(BiTree T, BiTree& NewT)//复制二叉树

{

if (T == NULL)

{

NewT = NULL;

return OK;

}

else

{

NewT = (BiTNode*)malloc(sizeof(BiTNode));

NewT = new BiTNode;

NewT->data = T->data;

CopyBiTree(T->lchild, NewT->lchild);

CopyBiTree(T->rchild, NewT->rchild);

}

}

int Depth(BiTree T)//计算树的深度

{

int m = 0;

int n = 0;

if (T == NULL)

{

return 0;

}

else

{

m = Depth(T->lchild);

n = Depth(T->rchild);

if (m > n)

{

return m + 1;

}

else

{

return n + 1;

}

}

}

int NodeCount(BiTree T)//计算二叉树结点总数

/*

如果是空树,则结点个数为0

否则,结点个数=左子树的结点个数+右子树的结点个数+1

*/

{

if (T == NULL)

{

return 0;

}

else

{

return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;

}

}

int LeafCount(BiTree T)//计算二叉树叶子结点总数

/*

如果是空树,则叶子结点个数为0

否则,叶子结点个数=左子树叶子结点个数+右子树叶子结点个数

这里不用+1,因为子树的根节点一定不是叶子结点

*/

{

if (T == NULL)

{

return 0;

}

if (T->lchild == NULL && T->rchild == NULL)//如果是叶子结点返回1

{

return 1;

}

else

{

return LeafCount(T->lchild) + LeafCount(T->rchild);

}

}



Status InitStack(SqStack& 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;

}

Status StackEmpty(SqStack S)//判断栈是否为空

{

if (S.top == S.base)

{

return TRUE;

}

else

{

return FALSE;

}

}

Status Push(SqStack& S, SElemType e)//顺序栈的入栈

{

if (S.top - S.base >= S.stacksize)

{

SElemType* New_ptr = (SElemType*)realloc(S.base, ((S.stacksize) + STACKINCREMENT) * sizeof(SElemType));

if (!New_ptr)

{

exit(OVERFLOW);

}

S.base = New_ptr;

S.top = S.base + S.stacksize;

S.stacksize += STACKINCREMENT;

}

*S.top++ = e;

return OK;

}

Status Pop(SqStack& S, SElemType& e)//顺序栈的出栈

{

if (S.top == S.base)

{

return ERROR;

}

e = *--S.top;

return OK;

}


Status InitQueue(LinkQueue& Q)//链队列的初始化

{

Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));

if (!Q.front)

{

exit(OVERFLOW);

}

Q.front->next = NULL;

return OK;

}

Status EnQueue(LinkQueue& Q, QElemType e)//入队

{

QNode* p = (QueuePtr)malloc(sizeof(QNode));

if (!p)

{

exit(OVERFLOW);

}

p->data = e;

p->next = NULL;

Q.rear->next = p;

Q.rear = p;

return OK;

}

Status DeQueue(LinkQueue& Q, QElemType& e)//出队

{

if (Q.front == Q.rear)

{

return ERROR;

}

QNode* p = Q.front->next;

e = p->data;

Q.front->next = p->next;

if (Q.rear == p)//注意这里要考虑到,当队列中最后一个元素被删后,队列尾指针也丢失了,因此需对队尾指针重新复制(指向头结点)

{

Q.rear = Q.front;

}

free(p);

return OK;

}

Status QueueEmpty(LinkQueue Q)//队列是否为空

{

if (Q.front == Q.rear)

{

return TRUE;

}

return FALSE;

}


《数据结构(C语言版)》二叉树的实现的评论 (共 条)

分享到微博请遵守国家法律