《洋葱》: 如果你愿意一层一层的剥开我的心
会发现 会流泪 我就是你失散多年的二叉树啊~
几个要点:
1.来自: lm_whales
struct XXX *p = //结构体指针类型
(struct XXX *) //强制转换成结构体指针类型
malloc(
sizeof(struct XXX) //结构体的大小
);
2.来自:2015年数据结构联考复习指导
n个结点的满二叉树,约定编号从根结点起(根结点编号为1),自上而下,自左向右,每个结点对应一个编号,对于编号为i的结点,如果有双亲,则其双亲结点为┕ i/2 ┙(下取整),如果有左孩子,则左孩子为2i,如果有右孩子,则右孩子为2i+1。
3.
所谓的逐层建立满二叉树,就是定义一个有左、右孩子指针和数据域的结点,然后把该结点填充进一个数组里,每次迭代修改结点的左右孩子指针,所按照的规则就是前面所说的结点编号的规则。为实现迭代修改,需要两个计数器i和j,i用来记录结点编号,j则是在每次修改右孩子指针的时候+1。比如:i=3的结点处j=3mod2=1, 即下一层的父结点。
下面是具体实现的代码
structlib.h
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include<string.h>
//自定义类型
typedef char ElemType;
//定义线索二叉树结构
typedef struct THREAD{
ElemType data; //数据域
struct THREAD *lchild, *rchild; //左右孩子指针
}Thread, *ThreadPoint;
main.c
#include "structlib.h"
int len;
int i=0,j=0; //次数
ThreadPoint tp[1024];
//操作结果:层次遍历构造二叉树
int createBinaryTree(ElemType *branch){
ThreadPoint curr;
curr = (ThreadPoint)malloc(sizeof(Thread));
curr->data = *branch; //结点的值
curr->lchild = NULL; //左子树置空
curr->rchild = NULL; //右子树置空
tp[i] = curr; //添加结点
if (i == 0){
++i;
createBinaryTree(branch + 1);
}
if (i % 2 == 0 && i != 0){
++j; //每次到右子树时,j+1,则tp[j]就能实现同一层结点的遍历
tp[j]->rchild = curr; //右子树
}
else if (i % 2 == 1){
tp[j]->lchild = curr; //左子树
}
if (i == (len - 1)){
return 1; //当i到达输入的末尾时,停止工作
}
i++; //为了上面的模运算 我也是拼了
createBinaryTree(branch + 1); //递归呗
}
//访问当前结点
void visit(ThreadPoint tp){
printf("%c",tp->data);
}
void main(){
ElemType * branch;
branch = (ElemType *)malloc(sizeof(ElemType)); //这行决定了你的指针是不是野指针
printf("请输入你要建立的二叉树序列【如:AEBCD】:");
scanf("%s",branch); //一次性输入
len = strlen(branch); //计算下长度
createBinaryTree(branch); //构造开始
printf("大爷,你要的二叉树做好了:");
for (int i = 0; i < len; i++){
visit(tp[i]);
}
printf("\n");
}