数据结构-二叉树(1)

来源:互联网 发布:java微信带参数二维码 编辑:程序博客网 时间:2024/05/16 18:43

树的概念和定义

1、  根:没有直接前驱

2、  子树:根下互不相交的有限集

3、  结点:包含一个数据元素和指向其他结点的分支信息

4、  结点的度:一个结点的子树称为此结点的度

5、  叶结点:度为零的结点

6、  分直结点:度不为零的结点

7、  孩子结点:一个结点的直接后继称为该结点的孩子结点

8、  双亲结点:一个结点的直接前继称为该结点的双亲结点

9、  兄弟结点:同一双亲结点的孩子结点之间互称兄弟结点

10、             祖先结点:从根结点到该结点的路径上的所有结点

11、             子孙结点:该结点的直接后继结点和间接后继结点

12、             树的度:树中所有结点的度的最大值

13、             结点的层次:从根结点开始定义,根结点的层次为1,根的直接后继的层次为2,一次类推

14、             树的高度(深度):树中所有结点的层次的最大值

15、             有序树:在树T中,如果各子树Ti之间是有先后次序的,则称为有序树

16、             森林:m(m>=0)棵互不相交的树的集合。

二叉树

1、  定义:(1)每个结点的度不大于2

      (2)每个结点的孩子结点次序不能任意颠倒

2、二叉树的性质:

性质1、在二叉树的第i层上只多有2^(i-1)个结点(i>=1)

性质2、深度为k的二叉树至多有(2^K)-1个结点(k>=1)

(2^0+2^1……+2^k-1)=2^k-1(数学知识要记得哦,等比数列公式)

性质3、对任意一棵二叉树T,若终端结点(叶结点)数为n0,而其度数为2的结点数为n2,则n0=n2+1

所有结点数n = n0+n1+n2(n1为度1的结点数)

每个结点都有对应一个进入它的分支,分支数目为B,则n=B+1

B=n1+2*n2, n=n1+2*n2+1=n0+n1+n2,所以:n0=n2+1

满二叉树:深度为k且有(2^-1)个结点的二叉树。

完全二叉树:深度为k,结点数为n的二叉树,如果其结点1-n的位置序号分为与满二叉树的结点1-n的位置序号一一相应,则为完全二叉树。

性质4:具有n个点结点的完全二叉树的深度为小于(log2)N的最大整数。

性质5:对于具有n个结点的完全二叉树,如果按照从上到下和从左到右的顺序对二叉树中的所有结点从1开始顺序编号,则对于任意的序号为i的结点有:

(1)  如果i=1,则序号为i的结点是根结点,无双亲结点;如果i>1,则序号为i的结点的双亲结点序号为小于i/2的最大整数。

(2)      如果2*i>n,则序号i的结点没有左孩子;如果2*i<=n,则序号为i的结点的左孩子的序号为 2*i.

(3)      如果2*i+1>n,则序号i的结点没有右孩子;如果2*i+1<=n,则序号为i的结点的右孩子的序号为2*i+1.


#include <iostream>
#include <malloc.h>
//#include "TreeNode.h"
using namespace std;


typedef struct TreeNode{
  int data;
  struct TreeNode * LChild;
  struct TreeNode * RChild;
}BNode , *BTree;
//void createTree(BTree *root);
//void preOrder(BTree root);
//void inOrder(BTree root);
//
//void posOrder(BTree root);

//创建二叉树,输出数字0,代表NULL
void createTree(BTree *root)
{
    int in = 0;
    scanf("%d",&in);
    if(in==0)(*root)=NULL;
    else{
     *root = (BTree)malloc(sizeof(BNode));
     (*root)->data = in;
     printf("%d:left:",in);
     createTree(&(*root)->LChild);
     printf("%d:right:",in);
     createTree(&(*root)->RChild);
    }
}
//递归先序遍历
void preOrder(BTree root){
    if(root != NULL){
        printf("%d,  ",root->data);
        preOrder(root->LChild);
        preOrder(root->RChild);
    }
}
//递归中序遍历
void inOrder(BTree root){
    if(root != NULL){
        inOrder(root->LChild);
        printf("%d,",root->data);
        inOrder(root->RChild);
    }
}
//递归后序遍历
void posOrder(BTree root){
    if(root != NULL){
        posOrder(root->LChild);
        posOrder(root->RChild);
        printf("%d,",root->data);
    }
}
//非递归先序遍历
void preOrder2(BTree root){
    BTree p ,stack[100];
    int top = 0;
    p = root;
    if(root != NULL){
        top = 1;
        stack[top] = p;
        while(top>0){
          p = stack[top];
          top--;
          printf("%d,",p->data);
          if(p->RChild != NULL){
           ++top;
           stack[top]=p->RChild;
          }
          if(p->LChild != NULL){
           ++top;
           stack[top]=p->LChild;
          }
        }
    }
}
//非递归中序遍历
void inOrder2(BTree root){
    BTree p,stack[100];
    p = root;
    int top = 0;
    while(p != NULL || top > 0){
     while(p != NULL){
         top++;
         stack[top]=p;
         p = p->LChild;
     }
     if(top > 0){
         p=stack[top];
         top--;
         printf("%d,",p->data);
         p=p->RChild;
     }
    }
}
//非递归后序遍历
void posOrder2(BTree root){
    BTree p,stack[100];
    int flag[100];
    p=root;
    int top = 0;
    while(root != NULL || top > 0){

        while(root){
            top++;
            flag[top]=0;
            stack[top]=root;
            root = root->LChild;
        }
        while(top>0&&flag[top]==1){
            root = stack[top];
            printf("%d,",root->data);
            top--;
        }
        if(top>0){
            root = stack[top];
            flag[top]=1;
            root = root->RChild;
        }else{
            root = NULL;
        }
    }
}
/*按照层次遍历二叉树*/
void levelOrder(BTree root){
    int front =0;
    int tear = 1;
    BTree queue[100];
    queue[0]=root;
    while(front < tear){
        if(queue[front]){
            printf("%d,",queue[front]->data);
            queue[tear++]=queue[front]->LChild;
            queue[tear++]=queue[front]->RChild;
            front++;
        }else{
            front++;
        }
    }
}
/*递归法将左右子树的互换*/
void exchange(BTree root){
    BTree bt;
    if(root){
        exchange(root->LChild);
        exchange(root->RChild);
        bt = root->LChild;
        root->LChild=root->RChild;
        root->RChild = bt;
    }
}
/*非递归法将二叉树的左右子树互换*/
void exchange2(BTree root){
    BTree bt;
    BTree stack[100];
    int top = 0;
    while(top>0 || root){
        if(root){
            top++;
            stack[top]=root;
            bt = root->LChild;
            root->LChild = root->RChild;
            root->RChild = bt;
            root  = root->LChild;
        }else{
            root = stack[top];
            top--;
            root = root->RChild;
        }
    }
}
//递归方法求二叉树叶子结点的个数
int leavesNum(BTree root){
   if(root){
       if(root->LChild == NULL && root->RChild == NULL){
            return 1;
       }
       return leavesNum(root->LChild)+leavesNum(root->RChild);
   }else{
        return 0;
   }
}
//非递归方法求二叉树叶子结点的个数
int leavesNum2(BTree root){
    BTree stack[100];
    int count = 0,top = 0;
    while(root || top > 0){
        if(root){
            top++;
            stack[top]=root;
            if(root->LChild == NULL && root->RChild ==NULL){
                count++;
            }
            root = root->LChild;
        }else{
            root = stack[top]->RChild;
            top--;
        }
    }
    return count;
}
int main()
{
    BTree b_header = NULL;
    //b_header = initTree(b_header);
    createTree(&b_header);
    printf("\n前序遍历结果:\n");
    preOrder(b_header);
    printf("\n中序遍历结果:\n");
    inOrder(b_header);
    printf("\n后序遍历结果:\n");
    posOrder(b_header);
    printf("\n非递归前序遍历结果:\n");
    preOrder2(b_header);
    printf("\n非递归中序遍历结果:\n");
    inOrder2(b_header);
    printf("\n非递归后序遍历结果:\n");
    posOrder2(b_header);
    printf("\n查询叶子结点个数:\n");
    int num = leavesNum(b_header);
    printf("%d",num);
    printf("\n非递归法查询叶子结点个数:\n");
    int num2 = leavesNum2(b_header);
    printf("%d",num2);
    return 0;
}




原创粉丝点击