数据结构——二叉树、哈希表 (DAY 6)

二叉树的特点

        二叉树是一种常见的数据结构,由节点组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树具有以下特点:

  1. 根节点:树的顶部节点,没有父节点。

  2. 叶子节点:没有子节点的节点。

  3. 内部节点:至少有一个子节点的节点。

  4. 子树:每个节点的左子节点和右子节点分别构成左子树和右子树。

二叉树的类型

  1. 满二叉树:每个节点都有0个或2个子节点。

  2. 完全二叉树:除了最后一层,其他层都是满的,且最后一层的节点尽可能靠左。

  3. 平衡二叉树:左右子树的高度差不超过1。

  4. 二叉搜索树(BST):左子节点的值小于父节点,右子节点的值大于父节点。

二叉树的遍历

  1. 前序遍历:根节点 -> 左子树 -> 右子树。

  2. 中序遍历:左子树 -> 根节点 -> 右子树。

  3. 后序遍历:左子树 -> 右子树 -> 根节点。

  4. 层序遍历:按层次从上到下、从左到右遍历。

哈希表

        1. 哈希:

                哈希算法:将数据根据哈希算法映射成唯一的键值

        2. 哈希表:

                数据通过哈希算法映射成唯一键值,存储在键值对应的位置,读取时可以根据键值快速读取

        3. 哈希碰撞、哈希冲突

                不同的数据通过哈希算法映射出来的键值相同

        4. 解决哈希碰撞:

        在键值相同的位置使用链表对数据链式存储

二叉树的实现(C语言)

#include "queue.h"
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>

treenode_t *create_complete_btree(int startno, int endno)
{
    treenode_t *pnode = NULL;
    
    pnode = malloc(sizeof(treenode_t));
    if (NULL == pnode)
    {
        return NULL;
    }

    pnode->no = startno;
    if (2 * startno <= endno)
    {
        pnode->pleftchild = create_complete_btree(2*startno, endno);
    }
    else
    {
        pnode->pleftchild = NULL;
    }
    if (2 * startno + 1 <= endno)
    {
        pnode->prightchild = create_complete_btree(2*startno+1, endno);
    }
    else
    {
        pnode->prightchild = NULL;
    }

    return pnode;
}

int preoder_traversal_btree(treenode_t *proot)
{
    if (NULL == proot)
    {
        return 0;
    }

    printf("%d ", proot->no);
    preoder_traversal_btree(proot->pleftchild);
    preoder_traversal_btree(proot->prightchild);

    return 0;
}

int inoder_traversal_btree(treenode_t *proot)
{
    if (NULL == proot)
    {
        return 0;
    }

    inoder_traversal_btree(proot->pleftchild);
    printf("%d ", proot->no);
    inoder_traversal_btree(proot->prightchild);

    return 0;
}

int postoder_traversal_btree(treenode_t *proot)
{
    if (NULL == proot)
    {
        return 0;
    }

    postoder_traversal_btree(proot->pleftchild);
    postoder_traversal_btree(proot->prightchild);
    printf("%d ", proot->no);

    return 0;
}

int layerout_traversal_tree(treenode_t *proot)
{
    struct list_head *pqueue = NULL;
    treenode_t *pnode = NULL;

    pqueue = create_queue();
    enter_queue(pqueue, proot);

    while (!is_empty_queue(pqueue))
    {
        pnode = quit_queue(pqueue);
        printf("%d ", pnode->no);

        if (pnode->pleftchild != NULL)
        {
            enter_queue(pqueue, pnode->pleftchild);      
        }
        if (pnode->prightchild != NULL)
        {
            enter_queue(pqueue, pnode->prightchild);
        }
    }

    destroy_queue(&pqueue);

    return 0;
}

int destroy_btree(treenode_t **pproot)
{
    if (NULL == *pproot)
    {
        return 0;
    }

    destroy_btree(&(*pproot)->pleftchild);
    destroy_btree(&(*pproot)->prightchild);
    free(*pproot);

    return 0;
}

int get_btree_high(treenode_t *proot)
{
    int left_high = 0;
    int right_high = 0;

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

    left_high = get_btree_high(proot->pleftchild);
    right_high = get_btree_high(proot->prightchild);

    return (left_high > right_high ? left_high : right_high) + 1;
}

int preorder_btree_stack(treenode_t *proot)
{
    struct list_head *pstack = NULL;
    treenode_t *pnode = NULL;

    pstack = create_stack();

    pnode = proot;
    
    while (1)
    {
        while (pnode != NULL)
        {
            printf("%d ", pnode->no);
            push_stack(pstack, pnode);
            pnode = pnode->pleftchild;
        }

        if (IS_EMPTY_STACK(pstack))
        {
            break;
        }

        pnode = pop_stack(pstack);

        pnode = pnode->prightchild;
    }
    
    destroy_stack(&pstack);

    return 0;
}

int inorder_btree_stack(treenode_t *proot)
{
    struct list_head *pstack = NULL;
    treenode_t *pnode = NULL;

    pstack = create_stack();

    pnode = proot;
    
    while (1)
    {
        while (pnode != NULL)
        {
            push_stack(pstack, pnode);
            pnode = pnode->pleftchild;
        }

        if (IS_EMPTY_STACK(pstack))
        {
            break;
        }

        pnode = pop_stack(pstack);
        printf("%d ", pnode->no);
        pnode = pnode->prightchild;
    }
    
    destroy_stack(&pstack);

    return 0;
}

int postorder_btree_stack(treenode_t *proot)
{
    struct list_head *pstack = NULL;
    treenode_t *pnode = NULL;

    pstack = create_stack();

    pnode = proot;
    
    while (1)
    {
        while (pnode != NULL)
        {
            pnode->mode = 1;
            push_stack(pstack, pnode);
            pnode = pnode->pleftchild;
        }

        if (IS_EMPTY_STACK(pstack))
        {
            break;
        }

        pnode = pop_stack(pstack);
        if (1 == pnode->mode)
        {
            pnode->mode = 2;
            push_stack(pstack, pnode);
            pnode = pnode->prightchild;
        }
        else if (2 == pnode->mode)
        {
            printf("%d ", pnode->no);
            pnode = NULL;
        }
    }
    
    destroy_stack(&pstack);

    return 0;
}
#include "queue.h"
#include <stdio.h>
#include <stdlib.h>

struct list_head *create_queue(void)
{
    struct list_head *phead = NULL;

    phead = malloc(sizeof(struct list_head));
    if (NULL == phead)
    {
        return NULL;
    }
    
    INIT_LIST_HEAD(phead);

    return phead;
}

int is_empty_queue(struct list_head *phead)
{
    return list_empty(phead);
}

int enter_queue(struct list_head *phead, treenode_t *tmpdata)
{
    queue_t *ptmpnode = NULL;

    ptmpnode = malloc(sizeof(queue_t));
    if(NULL == ptmpnode)
    {
        return -1;
    }

    ptmpnode->data = tmpdata;

    list_add_tail(&ptmpnode->node, phead);

    return 0;
}

treenode_t *quit_queue(struct list_head *phead)
{
    queue_t *ptmpnoded = NULL;
    treenode_t *tmpdata;
   
    ptmpnoded = list_entry(phead->next, queue_t, node);

    tmpdata = ptmpnoded->data;

    list_del(&ptmpnoded->node);

    free(ptmpnoded);

    return tmpdata;
}

int destroy_queue(struct list_head **pphead)
{
    while (!is_empty_queue(*pphead))
    {
        quit_queue(*pphead);
    }

    free(*pphead);
    *pphead = NULL;

    return -1;
}
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>

struct list_head *create_stack(void)
{
    struct list_head *phead = NULL;

    phead = malloc(sizeof(struct list_head));
    if (NULL == phead)
    {
        return NULL;
    }

    
    INIT_LIST_HEAD(phead);

    return phead;
}

int push_stack(struct list_head *phead, treenode_t *tmpdata)
{
    stack_node_t *ptmpnode = NULL;

    ptmpnode = malloc(sizeof(stack_node_t));
    if(NULL == ptmpnode)
    {
        return -1;
    }

    ptmpnode->data = tmpdata;

    list_add(&ptmpnode->node, phead);

    return 0;
}

treenode_t *pop_stack(struct list_head *phead)
{
    stack_node_t *ptmpnoded = NULL;
    treenode_t *tmpdata = 0;
   
    if (IS_EMPTY_STACK(phead))
    {
        return NULL;
    }

    ptmpnoded = list_entry(phead->next, stack_node_t, node);

    tmpdata = ptmpnoded->data;

    list_del(&ptmpnoded->node);

    free(ptmpnoded);

    return tmpdata;
}

int destroy_stack(struct list_head **pphead)
{
    while (!IS_EMPTY_STACK(*pphead))
    {
        pop_stack(*pphead);
    }

    free(*pphead);
    *pphead = NULL;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值