循环队列 、二叉树

1、循环队列

        特点:只允许在队尾入队,队头出队,遵循先进先出原则

                不能随机访问,不能随机插入

        1.1循环队列创建

                定义两个指针分别指向队头,队尾。初始化队头,队尾为0;

SeqQueue *CreateSeqQueue(int MaxLen)
{
    SeqQueue *pTmpQueue = NULL;
    
    pTmpQueue = malloc(sizeof(SeqQueue));
    if (NULL == pTmpQueue)
    {
        return NULL;
    }

    pTmpQueue->Head = pTmpQueue->Tail = 0;
    pTmpQueue->Len = MaxLen;
    pTmpQueue->pData = malloc(sizeof(DataType) * MaxLen);
    if (NULL == pTmpQueue->pData)
    {
        return NULL;
    }

    return pTmpQueue;
}

        1.2判断循环队列是否存满,是否为空

        当队尾与队头相同时,队列为空;当队尾+1对队头取余等于队头时表示队列存满;

int IsEmptySeqQueue(SeqQueue *pTmpQueue)
{
    return pTmpQueue->Head == pTmpQueue->Tail ? 1 : 0;
}

int IsFullSeqQueue(SeqQueue *pTmpQueue)
{
    return (pTmpQueue->Tail + 1) % pTmpQueue->Len == pTmpQueue->Head ? 1 : 0;
}

        1.3入队,出队

int EnterSeqQueue(SeqQueue *pTmpQueue, DataType TmpData)
{
    if (IsFullSeqQueue(pTmpQueue))
    {
        return -1;
    }

    pTmpQueue->pData[pTmpQueue->Tail] = TmpData;
    pTmpQueue->Tail = (pTmpQueue->Tail + 1) % pTmpQueue->Len;

    return 0;
}

DataType QuitSeqQueue(SeqQueue *pTmpQueue)
{
    DataType TmpData;

    TmpData = pTmpQueue->pData[pTmpQueue->Head];
    pTmpQueue->Head = (pTmpQueue->Head + 1) % pTmpQueue->Len;

    return TmpData;
}

2、二叉树

        2.1概念

        树:只有一个前驱,但是可以有多个后继
        根节点:最顶层节点(没有前驱)
        分支节点:有前驱也有后继
        叶子节点:没有后继的节点
        层:根节点所在为第一层,每过一个分支节点,层数+1 
        深度: 从根节点出发到达节点的分支节点个数称为该节点的深度
        高度:从叶子节点出发到该节点最大的节点个数称为该节点的高度

        树的高度:整个树形结构中高度最高的节点的高度称为树的高度
        树的深度:整个树形结构中深度最深的节点的深度称为树的深度
        树的层数 == 树的高度 == 树的深度

        满二叉树:满二叉树是一种特殊的二叉树,其中每个层级的节点数都是最大值,即每个层级都是完全填充的
        完全二叉树:所有节点展开后,节点编号排列连续

        2.2二叉树创建

TreeNode *CreateDoubleTree(int Start, int End)
{
    TreeNode *pTmpTree = NULL;

    pTmpTree = malloc(sizeof(TreeNode));
    if (NULL == pTmpTree)
    {
        return NULL;
    }
    
    pTmpTree->No = Start;
    pTmpTree->pChildLeft = pTmpTree->pChildRight = NULL;

    if (2 * Start <= End)
    {
        pTmpTree->pChildLeft = CreateDoubleTree(2 * Start, End);
    }
    if (2 * Start + 1 <= End)
    {
        pTmpTree->pChildRight = CreateDoubleTree(2 * Start + 1, End);
    }

    return pTmpTree;
}

        2.3二叉树遍历(递归)

        前序遍历,中序遍历,后续遍历

//前序遍历(根左右)
int PreOrderTreeNode(TreeNode *pRoot)
{
    printf("%c ", pRoot->data);

    if (pRoot->pChildLeft != NULL)
    {
        PreOrderTreeNode(pRoot->pChildLeft);
    }
    if (pRoot->pChildRight != NULL)
    {
        PreOrderTreeNode(pRoot->pChildRight);
    }

    return 0;
}

//中序遍历(左根右)
int InOrderTreeNode(TreeNode *pRoot)
{
    if (pRoot->pChildLeft != NULL)
    {
        InOrderTreeNode(pRoot->pChildLeft);
    }

    printf("%c ", pRoot->data);

    if (pRoot->pChildRight != NULL)
    {
        InOrderTreeNode(pRoot->pChildRight);
    }

    return 0;
}

//后续遍历(左右根)
int LastOrderTreeNode(TreeNode *pRoot)
{
    if (pRoot->pChildLeft != NULL)
    {
        LastOrderTreeNode(pRoot->pChildLeft);
    }
    if (pRoot->pChildRight != NULL)
    {
        LastOrderTreeNode(pRoot->pChildRight);
    }

    printf("%c ", pRoot->data);

    return 0;
}

        2.4二叉树遍历(非递归)

        层序遍历,前序遍历,中序遍历

//层序遍历
int LayerOrderBinTree(TreeNode *pRoot)
{
    struct list_head head;
    Que_t *pTmpNode = NULL;
    Que_t *pFreeNode = NULL;

    //树形结构为NULL直接返回
    if (pRoot == NULL)
    {
        return -1;
    }
    
    //初始化队列
    INIT_LIST_HEAD(&head);
    
    //申请一个节点(将树形结构地址放入链表中)
    pTmpNode = malloc(sizeof(Que_t));
    if (pTmpNode == NULL)
    {
        return -1;
    }
    pTmpNode->pData = pRoot;
    
    //入队
    list_add_tail(&pTmpNode->node, &head);

    //只要队列不为NULL,出队一个元素,打印该元素,左右孩子不为NULL,入队
    while (!list_empty(&head))
    {
        //获得队头元素
        pFreeNode = list_entry(head.next, Que_t, node);
        printf("%c ", pFreeNode->pData->data);
        
        //队头元素的左孩子入队
        if (NULL != pFreeNode->pData->pChildLeft)
        {
            pTmpNode = malloc(sizeof(Que_t));
            if (NULL == pTmpNode)
            {
                return -1;
            }
            pTmpNode->pData = pFreeNode->pData->pChildLeft;
            list_add_tail(&pTmpNode->node, &head);
        }
        

        //队头元素的右孩子入队
        if (NULL != pFreeNode->pData->pChildRight)
        {
            pTmpNode = malloc(sizeof(Que_t));
            if (NULL == pTmpNode)
            {
                return -1;
            }
            pTmpNode->pData = pFreeNode->pData->pChildRight;
            list_add_tail(&pTmpNode->node, &head);
        }

        //队头元素出队
        list_del(&pFreeNode->node);
        
        //释放该节点
        free(pFreeNode);
    }
    
    return 0;    
}

//前序遍历(非递归)
int PreOrderTreeNodeByStack(TreeNode *pRoot)
{
    struct list_head stack;
    TreeNode *pTmpNode = NULL;
    Que_t *pFreeNode = NULL;
    Que_t *pHeadNode = NULL;

    //树型结构为NULL时返回
    if (NULL == pRoot)
    {
        return -1;
    }

    //初始栈
    INIT_LIST_HEAD(&stack);

    //定义指针指向根
    pTmpNode = pRoot;

    //遍历树型结构,当栈为空时结束
    while (1)
    {   
        //当根不为空时,循环
        while (pTmpNode != NULL)
        {
            //申请空间
            pHeadNode = malloc(sizeof(Que_t));
            if (pHeadNode == NULL)
            {
                return -1;
            }
            //将根指针存入
            pHeadNode->pData = pTmpNode;
            //加入栈
            printf("%c ", pHeadNode->pData->data);
            list_add(&pHeadNode->node, &stack);
            //当左孩子为空时结束
            pTmpNode = pTmpNode->pChildLeft;    
        }

        if (list_empty(&stack))
        {
            break;
        }

        //出栈
        pFreeNode = list_entry(stack.next, Que_t, node);
        list_del(&pFreeNode->node);
        //做孩子为空时判断右孩子
        pTmpNode = pFreeNode->pData->pChildRight;
        //释放空间
        free(pFreeNode);
    }

    return 0;
}

//中序遍历(非递归)
int InOrderTreeNodeByStack(TreeNode *pRoot)
{
    struct list_head stack;
    Que_t *pNewNode = NULL;
    Que_t *pFreeNode = NULL;
    TreeNode *pTmpNode = NULL;

    if (NULL == pRoot)
    {
        return -1;
    }

    INIT_LIST_HEAD(&stack);

    pTmpNode = pRoot;

    while (1)
    {
        while (pTmpNode != NULL)
        {
            pNewNode = malloc(sizeof(Que_t));
            if (NULL == pNewNode)
            {
                return -1;
            }
            pNewNode->pData = pTmpNode;
            
            list_add(&pNewNode->node, &stack);
            pTmpNode = pTmpNode->pChildLeft;
            
        }
        
        if (list_empty(&stack))
        {
            break;
        }
    
        pFreeNode = list_entry(stack.next, Que_t, node);
        list_del(&pFreeNode->node);

        printf("%c ", pFreeNode->pData->data);

        pTmpNode = pFreeNode->pData->pChildRight;
        
        free(pFreeNode);

        
    }

    return 0;
}

        2.5获取二叉树高度(层数,深度)

        树的高度=层数=深度

int GetBinTreeHeigh(TreeNode *pRoot)
{
    int LeftHeigh = 0;
    int RightHeigh = 0;

    if (NULL == pRoot)
    {
        return 0;
    }

    LeftHeigh = GetBinTreeHeigh(pRoot->pChildLeft);
    RightHeigh = GetBinTreeHeigh(pRoot->pChildRight);

    return (LeftHeigh > RightHeigh ? LeftHeigh : RightHeigh) + 1;
}

        2.6创建非完全二叉树

//创建非完全二叉树
TreeNode *CreateIncompleteBinTree(void)
{
    char pTmpData = 0;
    TreeNode *pTmpNode = NULL;

    scanf(" %c", &pTmpData);

    if ('#' == pTmpData)
    {
        return NULL;
    }
    else
    {
        pTmpNode = malloc(sizeof(TreeNode));
        if (pTmpNode == NULL)
        {
            return NULL;
        }

        pTmpNode->data = pTmpData;
        pTmpNode->pChildLeft = CreateIncompleteBinTree();
        pTmpNode->pChildRight = CreateIncompleteBinTree();
    }

    return pTmpNode;
}

你可能感兴趣的:(服务器,linux,c语言,学习,软件构建,数据结构)