Loading

首页

基本定义

由n(n>0)节点构成的有限集,构成一种层次的线性结构,在任意的一颗非空树中:

  1. 有且只有一个根节点

  2. 当n>1时,其余的节点可以分为m个互不相交的有限集,每个节点都可以看为一颗树

入度 <= 1;

出度 任意

结点的度: 出度数量

结点的层次(高度): 相对与根结点的距离

特殊的树(分而治之)

  • 二叉树:度 <= 2
  • 二叉搜索树(BST): 左 < 根 < 右
  • 满二叉树: 除最底层外,结点度均为2
  • 完全二叉树:满二叉树的最底层结点从左到右连续排列

树的基本性质

  1. 第n层的结点的个数<=

    2^i-1

  2. 高度为K的二叉树最多:

2^0 + 2^1 + 2^1 + .....2^{k-1} = 2^k -1

  1. 对于任意一颗二叉树

N0+N1+N2 = N1+2*N2+1

N0=N2+1

  1. 一个完全二叉树

    父结点的编号:

i/2

​ 左子结点的编号:

2*i

​ 右子结点的编号:

2*i+1

  1. 判断完全二叉树的最大深度k -已知总结点数量 n

k=log{2^n+1}

已知:此树为完全二叉树;总结点为n,

目标:

  1. 最后一个非叶子结点的位置 - n/2
  2. 叶子结点的总数 - (n+1)/2

叶子结点的总数:[n/2] (n+1)/2

解题思路:

求出最后一个叶子结点-n1

n1的父结点

树的实现

二叉排序树的创建

规则: 左 < 根 < 右

链式结构:

typedef int TreeElemtype;
typedef struct NODETREE
{
    TreeElemtype data;		//树中数据
    struct NODETREE *left;	//左子树
    struct NODETREE *right;	//右子树
} NodeTree;
typedef struct TREE
{
    NodeTree *root;		//根节点
    int deep;			//深度
} Tree
    
/*
    treeAddNumD:递归插入树
    参数:tree-目标树,num-插入元素
    返回:下层树
*/
Tree treeAddNumD(Tree *tree,TreeElemtype num);
//测试数据
    treeAddNumD(tree,4);
    treeAddNumD(tree,2);
    treeAddNumD(tree,6);
    treeAddNumD(tree,1);
    treeAddNumD(tree,2);
    treeAddNumD(tree,5);
    treeAddNumD(tree,7);

2020-12-19_10-38

遍历方式

先序遍历

根 - 左 - 右

递归实现:

2020-12-19_11-10

代码实现
void nTreePerOrderD(NodeTree *root)
{
    if (root)
    {
        printf("%d ", root->data);
        nTreePerOrderD(root->left);
        nTreePerOrderD(root->right);
    }
}

迭代实现:

2020-12-19_11-10_1

代码实现
void nTreePerOrder(NodeTree *root)
{
    Stack *stack = StackInit();
    for (;;)
    {
        for (; root; root = root->left)
        {
            printf("%d ", root->data);
            StackPush(stack, root);
        }
        root = StackPop(stack);
        if (!root)
            break;
        root = root->right;
    }
    StackDel(stack);
}

中序遍历

左 - 根 - 右

后序遍历

左 - 右 - 根

层次遍历

迭代方式

2020-12-19_11-35

代码实现
void nTreeLevelOrder(NodeTree *root)
{
    Queue *queue = queueInit();
    NodeTree *q ;
    if(!root){
        return ;
    }
    queueIn(queue,root);
    for(;;){
        q = queueOut(queue);
        if(q)
        {
            printf("%d ",q->data);
            if (q->left)
            {
                queueIn(queue,q->left);
            }
            if(q->right)
            {
                queueIn(queue,q->right);
            }
        }else
        {
            break;
        }
    }
    queueDel(queue);
}

递归创建

2020-12-19_14-41

代码实现

int nTreeAddNumD(Tree *tree, TreeElemtype num)
{
    if (!tree)
    {
        return 1;
    }
    
    NodeTree *node = nodeTreeInit();
    node->data = num;
    if (!tree->root)
    {
        tree->deep = 1 ;
        tree->root = node;
        return 1;
    }

    int deep = 0; // 记录插入深度
    nTreeAddNodeD(tree->root, node,&deep);
    tree->deep > deep ? tree->deep : deep;
    return 0;
}

NodeTree *nTreeAddNodeD(NodeTree *root, NodeTree *node,int* deep)
{
    if (!root)
    {
        return node;
    }
    else
    {
        *deep = *deep+1;
        if (node->data >= root->data)
        {
            root->right = nTreeAddNodeD(root->right,node,deep);
        }else
        {
            root->left = nTreeAddNodeD(root->left,node,deep);
        }
        return root;
    }
}

查找上限值

2020-12-19_15-01

代码实现

NodeTree* nTreeCeilD(NodeTree *root, TreeElemtype num)
{
    if (!root)
    {
        return NULL;
    }
    if (num == root->data)
    {
        return root;
    }else if(num < root->data)
    {
        NodeTree* node = nTreeCeilD(root->left,num);
        if (!node)
        {
            return root;
        }else
        {
            return node;
        }
    }else
    {
        return nTreeCeilD(root->right,num);
    } 
}

删除节点

2020-12-19_16-23

代码实现:

NodeTree *nTreeDelHas(NodeTree *root, TreeElemtype num)
{
    if (!root)
    {
        return NULL;
    }
    if (num < root->data)
    {
        root->left = nTreeDelHas(root->left, num);
        return root;
    }
    else if (num > root->data)
    {
        root->right = nTreeDelHas(root->right, num);
        return root;
    }

    //查找
    if (root->right)
    {
        if (root->left)
        {
            // 都存在
            // 找替死鬼
            NodeTree *p = root->right;
            NodeTree *pre = root;

            if (!p->left)
            {
                root->data = p->data;
                root->right = p->right;
                nodeTreeDel(p);
                return root;
            }
            for(;p->left;pre=p,p=p->left);
            root->data= p->data;
            pre->left = p->right;
            nodeTreeDel(p);
            return root;
        }
        else
        {
            // 右存在
            NodeTree *node = root->right;
            nodeTreeDel(root);
            return node;            
        }
    }
    else
    {
        if (root->left)
        {
            //左存在
            NodeTree *node = root->left;
            nodeTreeDel(root);
            return node;
        }
        else
        {
            // 都不存在
            nodeTreeDel(root);
            return NULL;
        }
        
    }
}

平衡二叉树

左右子树的高度差不超过1;

平衡因子:左子树与右子树的高度之差的绝对值

不平衡结点:左右子树高度差大于1

破坏结点:新插入,导致结点不平衡的结点

1.插入之后,需要能够判断结点是否平衡

2.平衡处理

1. 左旋
  	1. 破坏结点在右子树的右边
2. 右旋
  	1. 破坏结点在左子树的左边
3. 左右旋
  	1. 破坏结点在左子树的右边
4. 右左旋
  	1. 破坏结点在右子树的左边
posted @ 2020-12-19 19:03  流缘飞雨  阅读(141)  评论(0)    收藏  举报