树和二叉树

1 树

  树的节点的子节点可以有多个。是n个节点的有限集。

  树的集合便是森林。

2 二叉树

  二叉树是另一种树型结构。特点是每个i二点之多右两颗子树,并且二叉树的子树有左右之分,次序不能任意颠倒。

  相关特征:

1 在二叉树的第i层之多有2的(i-1)次方(i>=1)

2 深度为k的二叉树之多有2的k次方减1。(等比数列)

3 对于任意的二叉树,叶子节点是n0,度为2的节点树为n2,则n0=n2+1.

  假设度为1的节点数位n1。则总结点数可以表示为: n=n1+n0+n2.。 同时利用分支 n=n1+2*n2+1,两式联立得出结论。

4 具有n个节点的二叉树的深度位ceil(log(n)) +1。

  

3 二叉树的遍历:

  二叉树的遍历有先序遍历,中序遍历,后序遍历。

  先序遍历:先访问根节点,之后左子树,最后才是右子树。

  中序遍历:先访问左子树,之后根节点,最后才是右子树。

  后序遍历:先访问左子树,之后右子树,最后才是根节点。

//串的定长存储表示
#define MAX_NODE 50
#define ERROR 0
#define OK 1
typedef int Status
#define MAX_ROW 100
#define MAX_SIZE 101
#define NULLKY '?'
typedef int elemtype;
typdef struct BTNode
{
    char data;
    struct BTNode* Lchild, * Rchild;
}BTNode;

  先序遍历:

  分别展示 递归算法和非递归算法

//DLR先序遍历(根节点 左 右)  LDR中序遍历  LRD后序遍历
//分别讨论递归算法和非递归算法
void PreorderTranspose(BTNode* T)
{
    if (T != NULL)
    {
        visit(T->data);
        PreorderTranspose(T->Lchild);
        PreorderTranspose(T->Rchild);
    }
}
//先序遍历 非递归算法   一次遍历中 左 记录下右节点
void PreorderTraverse(BTNode* T)
{
    BTNode* Stack[MAX_NODE], * p=T, * q;
    int top = 0;
    if (T == NULL) cout << "Binary Tree is Empty!" << endl;
    else
    {
        do
        {
            visit(p->data); q = p->Rchild;
            if (q != NULL)Stack[++top] = q;
            p = p->Lchild;
            if (p == NULL) { p = Stack[top]; top--; }
        } while (p != NULL);
    }
}

  中序遍历:

  分别展示 递归算法和非递归算法

//中序遍历   左 根 右
void InorderTraverse(BTNode* T)
{
    if (T != NULL)
    {
        InorderTraverse(T->Lchild);
        visit(T->data);
        InorderTraverse(T->Rchild);
    }
}
//中序遍历 非递归算法    Stack存储根节点
void IreorderTraverse(BTNode* T)
{
    BTNode* Stack[MAX_NODE], * p=T;
    int top = 0, bool = 1;
    if (T == NULL) cout << "Binary Tree is Empty!" << endl;
    else
    {
        do
        {
            while(p!=NULL)
            {
                Stack[++top] = p; p = p->Lchild;
            }
            if (top == 0)bool = 0;
            else
            {
                p = Stack[top]; top--;
                visit(p->data); p = p->Rchaild;
            }
        } while (bool != 0);
            
    }
}

  后序遍历

  分为递归和非递归

//后序遍历 左 右 根
void PostorderTraverse(BTNode* T)
{
    if (T != NULL)
    {
        PostorderTraverse(T->Lchild);
        PostorderTraverse(T->Rchild);
        visit(T->data);
    }
}
void PostorderTranverse(BTNode* T)
{
    BTNode* Sa[MAX_NODE], * p = T;
    int Sb[MAX_NODE], top = 0, bool = 1;
    if (T == NULL)cout << "Binary Tree is Empty!" << endl;
    else {
        do {
            while (p != NULL)
            {
                Sa[++top] = p; Sb[top] = 0;
                p = p->Lchild;
            }
            if (top == 0)bool = 0;
            else if(Sb[top]==0)
            {
                p = Sa[top]->Rchild; Sb[top] = 1;
            }
            else {
                p = Sa[top]; top--;
                visit(p->data); p = NULL;
            }
        } while (bool != 0);
    }
}

4 二叉树的层次遍历,遵循自上而下,自左而右的遍历方式。

//层次二叉树 遍历  自上而下  自左而右
void LevelorderTraverse(BTNode* T)
{
    BTNode* Queue[MAX_NODE], * p = T;
    int front = 0; rear = 0;
    if (p != NULL)
    {
        Queue[++rear] = p;
        while (front < rear)
        {
            p = Queue[++front]; visit(p->data);
            if (p->Lchild != NULL)
                Queue[++rear] = p->Lchild;
            if (p->Rchild != NULL)
                Queue[++rear] = p->Rchild;
        }
    }
}

5 建二叉树

  层次建树:遵循自上而下,自左而右,返回根指针

//按照满二叉树链表创建  返回指向根节点的指针变量  自上而下 自左而右
BTNode* Create_BTree(void)
{
    BTNode* T, * p, * s[MAX_NODE];
    char ch; int i, j;
    while (true)
    {
        cin >> i;
        if (i == 0)break;
        else {
            cout << "请输入字符" << endl;
            cin >> ch;; p = (BTNode*)malloc(sizeof(BTNode));
            p->data = ch;
            p->Lchild = p->Rchild = NULL; s[i] = p;
            if (i == 1)T = p;
            else
            {
                j = ceil(i / 2);
                if (i % 2 == 0)s[j]->Lchild = p;
                else s[j]->Rchild = p;
            }
        }
    }
    return T;
}

  按照先序方式建立二叉树:

//按照先序遍历方式 建立
BTNode* Preorder_Create_BTree(BTNode* T)
{
    char ch;
    cout << "" << endl;
    cin >> ch;
    if(ch==NULLKY)
    {
        T = NULL;
        return(T);
    }
    else
    {
        T = (BTNode*)malloc(sizeof(BTNode));
        T->data = ch;
        Preorder_Create_BTree(T ->Lchild);
        Preorder_Create_BTree(T ->Rchild);
        return T;
    }
} 

6 求二叉树的叶子节点和深度

  二叉树的叶子节点是 度为0的节点。叶子是指出度为0的结点,又称为终端结点。

//求二叉树的叶子节点数     先找的左下的叶子节点
int search_leaves(BTNode* T)
{
    BTNode* Stack[MAX_NODE], * p = T;
    int top = 0, num = 0;
    if (T != NULL)
    {
        stack{ ++top } = p;
        while (top > 0)
        {
            p = stack[top--];    //当节点左右节点都是NULL时,Stack中这个节点位置都会被左节点替代,从而跨越到本届点的右边
            if (p->Lchild == NULL && p->Rchild == NULL) num++;
            if (p->Rchild != NULL)
                stack[++top] = p->Rchild;
            if (p->Lchild != NULL)
                stack[++top] = p->Lchild;
        }
    }
    return num;
}

  深度:

高度和深度是相反的表示,深度是从上到下数的,而高度是从下往上数。

我们先来看看高度和深度的定义,某节点的深度是指从根节点到该节点的最长简单路径边的条数,而高度是指从该节点到叶子节点的最长简单路径边的条数。

注意:这里边的条数是规定根节点的深度和叶子节点的高度是0;

所以树的深度和高度是相等的,而对其他节点来说深度和高度不一定相等。

//求二叉树的深度  利用层次遍历法可以直接求二叉树的深度
int search_depth(BTNode* T)
{
    BTNode* Stack[MAX_NODE], * p = T;
    int front = 0, rear = 0, depth = 0, level;
    if (T != NULL)
    {
        Queue[++rear] = p;
        level = rear;
        while (front < rear)
        {
            p = Queue[++front];
            if (p->Lchild != NULL)
                Queue[++rear] = p;
            if (p->Rchild != NULL)
                Queue[++rear] = p;
            if(front==level)
            {
                depth++; level = rear;
            }
        }
    }
}

 

posted @ 2020-03-31 23:21  为红颜  阅读(221)  评论(0编辑  收藏  举报