摘要: 二叉树是树的特例,即每一个元素最多只能有两个分支。二叉树是十分重要的,一般的树都可以由二叉树转换过去并且一一对应。所以在我们熟练掌握二叉树之后,才能对一般的树进行操作。
今天我们会讲到二叉树的深度遍历、用层次遍历录入元素和用层次遍历输出元素。
一.代码块
1)创建
对于二叉树,我们一般都是用链式存储,顺序存储的话会造成很多空间的浪费
#define MAXSIZE 5
//对于二叉树,我们一般都是用链式存储,顺序存储的话会造成很多空间的浪费
typedef struct BTNode
{
char element;
//指向左孩子的指针
struct BTNode *left;
//指向右孩子的指针
struct BTNode *right;
}*BTNodePtr;
这里为了方便我们进行层次遍历,要创建一个循环队列,需要注意的是,这个1队列存储的元素都是一个个指向树结点的地址。
typedef struct BTNodeQueue
{
/*由于我们用的链式存储,所以所用的队列存储的就是地址,
所以数组的数据类型是指针。存储一系列的地址,
当然用这种动态数组啦*/
BTNodePtr* nodePtrs;
int front;
int rear;
}*BTNodeQueuePtr;
2)队列的初始化
BTNodeQueuePtr BTNodeQueueInit()
{
BTNodeQueuePtr resultPtr = (BTNodeQueuePtr)malloc(sizeof(struct BTNodeQueue));
//不要忘记给动态数组malloc哦
resultPtr->nodePtrs = (BTNodePtr*)malloc(MAXSIZE * sizeof(struct BTNode));
/*由于我们出队操作一次,通常会入队操作两次 ,
所以其实数组为5其实是有点小的 ,但在老师的例子中够用*/
resultPtr->front = 0;
resultPtr->rear = 0;
return resultPtr;
}
3)出队及入队
循环队列的操作等在我前面的文章有着详细的叙述,这里就不赘述了
void enqueue(BTNodeQueuePtr paraQueuePtr,BTNodePtr paraPtr)
{
if((paraQueuePtr->rear+1) % MAXSIZE == (paraQueuePtr->front) % MAXSIZE)
{
printf("队列满了,无法入队\n");
return ;
}
paraQueuePtr->nodePtrs[paraQueuePtr->rear % MAXSIZE] = paraPtr;
paraQueuePtr->rear = (paraQueuePtr->rear+1) % MAXSIZE;
}
BTNodePtr dequeue(BTNodeQueuePtr paraQueuePtr)
{
if(paraQueuePtr->front == paraQueuePtr->rear)
{
printf("队列为空,无法出队\n");
return ;
}
BTNodePtr tempPtr = paraQueuePtr->nodePtrs[paraQueuePtr->front % MAXSIZE];
paraQueuePtr->front = (paraQueuePtr->front+1) % MAXSIZE;
return tempPtr;
}
4)创建树结点
这里是将传入的字符创建为一个树结点,其左孩子和后孩子默认为NULL
BTNodePtr constructNode(char paraChar)
{
BTNodePtr tempPtr = (BTNodePtr)malloc(sizeof(struct BTNode));
tempPtr->element = paraChar;
tempPtr->left = NULL;
tempPtr->right = NULL;
return tempPtr;
}
5)将字符串转化为二叉树
层次遍历很好的运用了队列先进先出,后进后出的性质,读入一个元素,就创建一个树结点,并将其入队。出队一个结点就作为父结点,接下来两个元素分别为其左孩子和右孩子。
BTNodePtr stringToBT(char *paraString)
{
int i = 0;
char ch;
BTNodeQueuePtr resultQueuePtr = BTNodeQueueInit();
BTNodePtr headerPtr,tempParent,leftChild,rightChild;
ch = paraString[i];
i ++