二叉树

一、基本概念

二叉树的性质:
性质1:一棵非空二叉树的第i层上至多有2i-1个结点(i>1)。

性质2:深度为h的二叉树至多有2h-1个结点(h>1)。

(证明):根据性质1,二叉树中所有节点数为20+21+...+2h-1=2h-1

性质3:对于任意一棵二叉树,如果其叶子结点数为n0,度为2的结点数为n2,则n0=n2+1。

(证明):二叉树中所有结点数为:n=n0+n1+n2 。二叉树中有n-1条边,这些边由度为1和2的结点产生,即n-1=n1+2*n2,即n0+n1+n2=n1+2*n2+1,即n0=n2+1。

满二叉树:

所有叶子结点位于同一层,其它非叶子结点的度为2。若满二叉树的深度为h,则其所有结点数必为:2h-1。

 

 完全二叉树:

扣除最大层次那层后即成为一棵满二叉树,且层次最大那层的所有结点均向左靠齐。

 

完全二叉树的性质:若完全二叉树有n个结点,按照从上到下,从左往右的顺序,从1开始,给每个结点编号,对于编号为i的结点有:

(1)如果i>1,则序号为i的结点的双亲结点为:i/2取整。(如2,3结点的双亲结点都为1);如果i=1,则结点i为根节点。

(2)如果2i>n,则结点i无左子女(此时结点i为叶子节点);若2i<=n,则其左子女为2i。

(3)如果2i+1>n,则结点i无右子女;若2i+1<=n,则其右子女为2i+1。

 二、二叉树的存储结构

1.顺序存储

将各结点通过编号后,存入数组中。

 

 顺序存储结构代码实现:

typedef Maxsize 100
typedef char datatype;
typedef struct{
    datatype data;
    int lchild,rchild;
}node;
node tree[Maxsize];
int n;
int root;

 

2.链式存储

每个结点包含三个域,分别用指针记录该结点的属性值,及左右子树的位置。

 

 

 

 链式存储结构代码实现:

typedef char datatype;
typedef struct node{
    datatype data;
    struct node*lchild,*rchild;
}bintnode;
typedef bintnode *bintree;

 

三、二叉树的创建

使用createbintree()函数创建二叉树,使用链式存储结构。按照前序遍历的顺序输入二叉树各结点值,遇到空结点使使用#代替。

(例子:ab##c##)

 

 前序遍历顺序创建二叉树代码实现:

bintree createbintree(){
    char ch;
    bintree t;
    if((ch=getchar())=='#')
        t=NULL;
    else{
        t=(bintree)malloc(sizeof(bintnode));
        t->data=ch;
        t->lchild=createbintree();
        t->rchild=createbintree();
    }
    return t;
} 

 

四、二叉树的遍历

1.递归遍历

递归前序遍历:

void preorder(bintree t){
    if(t){
        printf("%c ",t->data);
        preorder(t->lchild);
        preorder(t->rchild);
    }
}

 

递归中序遍历:

void inorder(bintree t){
    if(t){
        inorder(t->lchild);
        printf("%c ",t->data);
        inorder(t->rchild);
    }
}

 

递归后续遍历:

void postorder(bintree t){
    if(t){
        postorder(t->lchild);
        postorder(t->rchild);
        printf("%c ",t->data);
    }
}

 

2.非递归遍历

在采用非递归实现时,需用一个栈来记录回溯点。

/* 用于遍历的栈 */
typedef struct {
    bintree data[100];
    int tag [100]; 
    int top;
}sequence_stack;

/* 入栈操作 */
void push(sequence_stack *s,bintree t){
    s->data[s->top]=t;
    s->top++; 
}

/* 出栈操作,取栈顶元素 */
bintree pop(sequence_stack *s){
    if(s->top!=0){
        s->top--;
        return (s->data[s->top]);
    }
    else
        return NULL;
}

 

非递归前序遍历:

void preorder(bintree t){
    printf("前序遍历:");
    sequence_stack s;
    s.top=0;
    while((t) || (s.top!=0)){
        if(t){
            printf("%c ",t->data);
            push(&s,t);
            t=t->lchild;
        }
        else{
            t=pop(&s);
            t=t->rchild;
        }
    }
}

 

非递归中序遍历:

void inorder(bintree t){
    printf("中序遍历:");
    sequence_stack s;
    s.top=0;
    while((t) || (s.top!=0)){
        if(t){
            
            push(&s,t);
            t=t->lchild;
        }
        else{
            t=pop(&s);
            printf("%c ",t->data);
            t=t->rchild;
        }
    }
} 

 

 

φ(゜▽゜*)♪ 感谢观看,希望对你有帮助!

posted @ 2022-11-24 15:08  Mr_宋先生  阅读(49)  评论(0编辑  收藏  举报