二叉树的特点
二叉树是一种常见的数据结构,由节点组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树具有以下特点:
-
根节点:树的顶部节点,没有父节点。
-
叶子节点:没有子节点的节点。
-
内部节点:至少有一个子节点的节点。
-
子树:每个节点的左子节点和右子节点分别构成左子树和右子树。
二叉树的类型
-
满二叉树:每个节点都有0个或2个子节点。
-
完全二叉树:除了最后一层,其他层都是满的,且最后一层的节点尽可能靠左。
-
平衡二叉树:左右子树的高度差不超过1。
-
二叉搜索树(BST):左子节点的值小于父节点,右子节点的值大于父节点。
二叉树的遍历
-
前序遍历:根节点 -> 左子树 -> 右子树。
-
中序遍历:左子树 -> 根节点 -> 右子树。
-
后序遍历:左子树 -> 右子树 -> 根节点。
-
层序遍历:按层次从上到下、从左到右遍历。
哈希表
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;
}