数据结构:创建二叉树且遍历二叉树
- 概念
一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。
二叉树的特点:
- 每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
- 二叉树的子树有左右之分,其子树的次序不能颠倒。
- 二叉树的存储结构
二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。
顺序存储:
顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储,关于堆我们后面的章节会专门讲解。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。
链式存储:
二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。链式结构又分为二叉链和三叉链,当前我们学习中一般都是二叉链,后面课程学到高阶数据结构如红黑树等会用到三叉链。
- 二叉树链式结构的遍历
common.h
#ifndef _COMMON_H_
#define _COMMON_H_
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
#include<stdlib.h>
#define ElemType int
void Swap(ElemType *a, ElemType *b)
{
ElemType tmp = *a;
*a = *b;
*b = tmp;
}
#endif /* _COMMON_H_ */
tree.h
#ifndef _TREE_H_
#define _TREE_H_
#include"common.h"
//二叉树节点类型
typedef struct BinTreeNode
{
ElemType data;
struct BinTreeNode *leftChild;
struct BinTreeNode *rightChild;
}BinTreeNode;
//二叉树
typedef struct BinTree
{
BinTreeNode *root;
}BinTree;
#define LEVEL_ORDER
#ifdef LEVEL_ORDER
//链式结构的结点类型
typedef struct LinkQueueNode
{
BinTreeNode* data;
struct LinkQueueNode *link;
}LinkQueueNode;
//链表
typedef struct LinkQueue
{
LinkQueueNode *front;
LinkQueueNode *rear;
}LinkQueue;
void LinkQueueInit(LinkQueue *pq);//链表初始化
void LinkQueueEnQue(LinkQueue *pq, BinTreeNode* x);//链表元素入队
void LinkQueueDeQue(LinkQueue *pq);//链表元素出队
void LinkQueuePrint(LinkQueue *pq);//打印链表
bool LinkQueueEmpty(LinkQueue *pq);//链表为空
BinTreeNode* LinkQueueFront(LinkQueue *pq);
void LinkQueueInit(LinkQueue *pq)
{
assert(pq != NULL);
pq->front = pq->rear = NULL;
}
void LinkQueueEnQue(LinkQueue *pq, BinTreeNode* x)
{
assert(pq != NULL);
LinkQueueNode *node = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
assert(node != NULL);
node->data = x;
node->link = NULL;
if (pq->front == NULL)
pq->front = pq->rear = node;
else
{
pq->rear->link = node;
pq->rear = node;
}
}
void LinkQueueDeQue(LinkQueue *pq)
{
assert(pq != NULL);
if (pq->front != NULL)
{
LinkQueueNode *p = pq->front;
pq->front = p->link;
free(p);
}
}
void LinkQueuePrint(LinkQueue *pq)
{
assert(pq != NULL);
LinkQueueNode *p = pq->front;
while (p != NULL)
{
printf("%d ", p->data);
p = p->link;
}
printf("\n");
}
bool LinkQueueEmpty(LinkQueue *pq)
{
return pq->front == NULL;
}
BinTreeNode* LinkQueueFront(LinkQueue *pq)
{
assert(pq->front != NULL);
return pq->front->data;
}
#endif
#define ORDER_NOR
#ifdef ORDER_NOR
//链栈
typedef struct LinkStackNode
{
BinTreeNode *data;
struct LinkStackNode *link; //next
}LinkStackNode;
typedef struct LinkStack
{
LinkStackNode *top;
}LinkStack;
void LinkStackInit(LinkStack *pst);
void LinkStackPush(LinkStack *pst, BinTreeNode * x);
void LinkStackPop(LinkStack *pst);
BinTreeNode * LinkStackTop(LinkStack *pst);
bool LinkStackEmpty(LinkStack *pst);
void LinkStackPrint(LinkStack *pst);
void LinkStackDestroy(LinkStack *pst);
void LinkStackInit(LinkStack *pst)
{
assert(pst != NULL);
pst->top = NULL;
}
void LinkStackPush(LinkStack *pst, BinTreeNode * x)
{
assert(pst != NULL);
LinkStackNode *node = (LinkStackNode*)malloc(sizeof(LinkStackNode));
assert(node != NULL);
node->data = x;
node->link = pst->top;
pst->top = node;
}
void LinkStackPop(LinkStack *pst)
{
assert(pst != NULL);
LinkStackNode *p = pst->top;
pst->top = p->link;
free(p);
}
BinTreeNode * LinkStackTop(LinkStack *pst)
{
assert(pst != NULL);
if (pst->top == NULL)
{
printf("栈已空,不能出栈.\n");
return;
}
return pst->top->data;
}
void LinkStackPrint(LinkStack *pst)
{
assert(pst != NULL);
LinkStackNode *p = pst->top;
while (p != NULL)
{
printf("%d\n", p->data);
p = p->link;
}
printf("\n");
}
void LinkStackDestroy(LinkStack *pst)
{
assert(pst != NULL);
while (pst->top != NULL)
{
LinkStackNode *p = pst->top;
pst->top = p->link;
free(p);
}
}
bool LinkStackEmpty(LinkStack *pst)
{
return pst->top == NULL;
}
#endif
void BinTreeInit(BinTree *pbt);
//创建
void BinTreeCreate(BinTree *bt);
void BinTreeCreate_1(BinTreeNode **t);
BinTreeNode* BinTreeCreate_2();
void BinTreeCreateByStr(BinTree *bt, const char *str);
BinTreeNode* BinTreeCreateByStr_1(const char *str, int *pindex);
//恢复二叉树
void BinTreeCreateByVLR_LVR(BinTree *bt, const char *VLR, const char *LVR);
BinTreeNode* BinTreeCreateByVLR_LVR_1(const char *VLR, const char *LVR, int n);
void BinTreeCreateByLRV_LVR(BinTree *bt, const char *VLR, const char *LVR);
BinTreeNode* BinTreeCreateByLRV_LVR_1(const char *VLR, const char *LVR, int n);
//递归遍历
void PreOrder(BinTree *bt);
void PreOrder_1(BinTreeNode *t);
void InOrder(BinTree *bt);
void InOrder_1(BinTreeNode *t);
void PostOrder(BinTree *bt);
void PostOrder_1(BinTreeNode *t);
void LevelOrder(BinTree *bt);
void LevelOrder_1(BinTreeNode *t);
//求二叉树的节点个数以及树的高度
int BinTreeCount(BinTree *bt);
int BinTreeCount_1(BinTreeNode *t);
int BinTreeHeight(BinTree *bt);
int BinTreeHeight_1(BinTreeNode *t);
//==================================================
void BinTreeInit(BinTree *pbt)
{
pbt->root = NULL;
}
void BinTreeCreate(BinTree *bt)
{
//1 BinTreeCreate_1(&bt->root);
//2
bt->root = BinTreeCreate_2();
}
void BinTreeCreate_1(BinTreeNode **t)
{
ElemType item;
scanf("%c", &item);
if (item == '#')
*t = NULL;
else
{
*t = (BinTreeNode*)malloc(sizeof(BinTreeNode));
assert(*t != NULL);
(*t)->data = item;
BinTreeCreate_1(&(*t)->leftChild);
BinTreeCreate_1(&(*t)->rightChild);
}
}
BinTreeNode* BinTreeCreate_2()
{
ElemType item;
scanf("%c", &item);
if (item == '#')
return NULL;
else
{
BinTreeNode *t = (BinTreeNode*)malloc(sizeof(BinTreeNode));
assert(t != NULL);
t->data = item;
t->leftChild = BinTreeCreate_2();
t->rightChild = BinTreeCreate_2();
return t;
}
}
void BinTreeCreateByStr(BinTree *bt, const char *str)
{
int index = 0;
bt->root = BinTreeCreateByStr_1(str, &index);
}
//"ABC##DE##F##G#H##";
BinTreeNode* BinTreeCreateByStr_1(const char *str, int *pindex)
{
if (str[*pindex] == '#' || str[*pindex] == '\0')
return NULL;
else
{
BinTreeNode *t = (BinTreeNode*)malloc(sizeof(BinTreeNode));
assert(t != NULL);
t->data = str[*pindex];
(*pindex)++;
t->leftChild = BinTreeCreateByStr_1(str, pindex);
(*pindex)++;
t->rightChild = BinTreeCreateByStr_1(str, pindex);
return t;
}
}
//恢复二叉树
void BinTreeCreateByVLR_LVR(BinTree *bt, const char *VLR, const char *LVR)
{
int n = strlen(VLR);
bt->root = BinTreeCreateByVLR_LVR_1(VLR, LVR, n);
}
BinTreeNode* BinTreeCreateByVLR_LVR_1(const char *VLR, const char *LVR, int n)
{
if (n == 0)
return NULL;
int k = 0;
while (VLR[0] != LVR[k])
k++;
BinTreeNode *t = (BinTreeNode*)malloc(sizeof(BinTreeNode));
assert(t != NULL);
t->data = LVR[k]; //VLR[0];
t->leftChild = BinTreeCreateByVLR_LVR_1(VLR + 1, LVR, k);
t->rightChild = BinTreeCreateByVLR_LVR_1(VLR + k + 1, LVR + k + 1, n - k - 1);
return t;
}
void BinTreeCreateByLRV_LVR(BinTree *bt, const char *VLR, const char *LVR);
BinTreeNode* BinTreeCreateByLRV_LVR_1(const char *VLR, const char *LVR, int n);
//遍历
void PreOrder(BinTree *bt)
{
PreOrder_1(bt->root);
}
void PreOrder_1(BinTreeNode *t)
{
if (t != NULL)
{
printf("%c ", t->data);
PreOrder_1(t->leftChild);
PreOrder_1(t->rightChild);
}
}
void InOrder(BinTree *bt)
{
InOrder_1(bt->root);
}
void InOrder_1(BinTreeNode *t)
{
if (t != NULL)
{
InOrder_1(t->leftChild);
printf("%c ", t->data);
InOrder_1(t->rightChild);
}
}
void PostOrder(BinTree *bt)
{
PostOrder_1(bt->root);
}
void PostOrder_1(BinTreeNode *t)
{
if (t != NULL)
{
PostOrder_1(t->leftChild);
PostOrder_1(t->rightChild);
printf("%c ", t->data);
}
}
void LevelOrder(BinTree *bt)
{
LevelOrder_1(bt->root);
}
void LevelOrder_1(BinTreeNode *t)
{
if (t != NULL)
{
LinkQueue Q;
LinkQueueInit(&Q);
LinkQueueEnQue(&Q, t);
while (!LinkQueueEmpty(&Q))
{
BinTreeNode *p = LinkQueueFront(&Q);
LinkQueueDeQue(&Q);
printf("%c ", p->data);
if (p->leftChild != NULL)
LinkQueueEnQue(&Q, p->leftChild);
if (p->rightChild != NULL)
LinkQueueEnQue(&Q, p->rightChild);
}
}
}
int BinTreeCount(BinTree *bt)
{
return BinTreeCount_1(bt->root);
}
int BinTreeCount_1(BinTreeNode *t)
{
if (t == NULL)
return 0;
else
return BinTreeCount_1(t->leftChild) + BinTreeCount_1(t->rightChild) + 1;
}
int BinTreeHeight(BinTree *bt)
{
return BinTreeHeight_1(bt->root);
}
int BinTreeHeight_1(BinTreeNode *t)
{
if (t == NULL)
return 0;
else
{
int left_h = BinTreeHeight_1(t->leftChild);
int right_h = BinTreeHeight_1(t->rightChild);
return (left_h > right_h ? left_h : right_h) + 1;
}
}
#endif/*_TREE_H_*/
- main.h
创建二叉树且进行遍历
#define _CRT_SECURE_NO_WARNINGS 1
#include"tree.h"
#include<windows.h>
void main()
{
//const char *str = "AB#DF###CE###";
const char *str = "ABC##DE##F##G#H##";
BinTree bt;
BinTreeInit(&bt);
//BinTreeCreate(&bt);
BinTreeCreateByStr(&bt, str);
printf("VLR: ");
PreOrder(&bt);
printf("\n");
printf("LVR: ");
InOrder(&bt);
printf("\n");
printf("LRV: ");
PostOrder(&bt);
printf("\n");
printf("Level: ");
LevelOrder(&bt);
printf("\n");
printf("Size = %d\n", BinTreeCount(&bt));
printf("Height = %d\n", BinTreeHeight(&bt));
system("pause");
}