1.二叉树的性质
二叉树是K叉树的特例,一个节点至多有俩个子树。
第N层上至多有2^(N-1)个元素。
深度为h的二叉树至多有2^(h)-1节点。
满二叉树:除了最深的一层其他层都是从左到右满层。
完全二叉树:除了叶节点所有节点都有左右两个子结点。
2.实现方式
数组
-
#define LENGTH 100 typedef char datatype; typedef struct node{ datatype data; int lchild,rchild; int parent; }Node; Node tree[LENGTH]; int length; int root;
-
链表
- typedef char datatype;
- typedef struct BinNode{
- datatype data;
- struct BinNode* lchild;
- struct BinNode* rchild;
- }BinNode;
- typedef BinNode* bintree;
前序:根节点->左子树->右子树
中序:左子树->根节点->右子树
后序:左子树->右子树->根节点
4.遍历的实现
以前序遍历为例
递归实现:
void preorder(bintree pbt)
{
if(pbt->data!=NULL)
print(pbt->data);
preorder(pbt->lchild);
preorder(pbt->rchild);
}
非递归实现
- #define SIZE 100
- typedef struct seqstack{
- bintree data[SIZE];
- int tag[SIZE]; //为后续遍历准备的
- int top; //top为数组的下标
- }seqstack;
- void push(seqstack *s,bintree t){
- if(s->top == SIZE){
- printf("the stack is full\n");
- }else{
- s->top++;
- s->data[s->top]=t;
- }
- }
- bintree pop(seqstack *s){
- if(s->top == -1){
- return NULL;
- }else{
- s->top--;
- return s->data[s->top+1];
- }
- }
- ##前序遍历
- void preorder(bintree t){
- seqstack s;
- s.top=-1;
- if(!t)
- print("NULL");
- else{
- while(t||s.top!=-1)
- {
- while(t){
- print(t->data);
- push(&s,t);
- t=t->lchild;
- }
- t=pop(&s);
- t=t->rchild;
- }
-
- }
- }
-
- ##中序遍历
- void midorder(bintree t){
- seqstack s;
- s.top=-1;
- if(!t)
- print("NULL");
- else{
- while(t||s.top!=-1)
- {
- while(t){
- push(&s,t);
- t=t->lchild;
- }
- t=pop(&s);
- print(t->data);
- t=t->rchild;
- }
-
- }
- }
- ##后序遍历
-
- void postorder_dev(bintree t){
seqstack s;
s.top = -1;
if(!t){
printf("the tree is empty!\n");
}else{
while(t || s.top != -1){ //栈空了的同时t也为空。
while(t){
push(&s,t);
s.tag[s.top] = 0; //设置访问标记,0为第一次访问,1为第二次访问
t= t->lchild;
}
if(s.tag[s.top] == 0){ //第一次访问时,转向同层右结点
t= s.data[s.top]; //左走到底时t是为空的,必须有这步!
s.tag[s.top]=1;
t=t->rchild;
}else {
while (s.tag[s.top] == 1){ //找到栈中下一个第一次访问的结点,退出循环时并没有pop所以为其左子结点
t = pop(&s);
printf("%c ",t->data);
}
t = NULL; //必须将t置空。跳过向左走,直接向右走
}
}
}
}
前序遍历: