一 树的基本概念
1.树 : 它是n个节点的集合,满足的条件
[1]只有一个根节点
[2]其它节点可以看成是多颗子树
2.树的高度 : 节点层数的最大值
3.树叶节点 : 没有子节点
4.二叉树 : 每个节点最多两个子节点
5.完全二叉树
(1)定义 : 只有最下面两层有度数小于2的节点,且最下面一层的叶节点在最左边
(2)特点 : 完全二叉树的编号是连续的[根节点编号为1,从上到下,从左到右]
(3)性质 : 对序号为k的节点
[1]左孩子存在的条件 2*k <= n ,存在其左孩子序号为2*k
[2]右孩子存在的条件 2*k + 1 <= n,存在其右孩子序号为2*k + 1
6.二叉树遍历
(1)前序遍历 : 根节点,左子树,右子树 [根,左,右] (递归)
(2)中序遍历 : 左子树,根节点,右子树 [左,根,右] (递归)
(3)后序遍历 : 左子树,右子树,根节点 [左,右,根] (递归)
(4)层次遍历 : 从根节点开始,一层一层的遍历 (非递归)
二 完全二叉树
(1)二叉树节点类型
(2)完全二叉树创建
注意:二叉树的创建没有统一的算法,需要根据其特性创建对应的二叉树
分析过程:
三 二叉树的层次遍历
核心思想:使用队列技术
[1]创建一个队列
[2]将根节点进队
[3]判断队列是否为空
[4]temp = 出队
[5]打印temp->data的值
[6]判断出队节点的左孩子是否存在,如果存在则将其左孩子进队
[7]判断出队节点的右孩子是否存在, 如果存在则将其右孩子进队
[8]继续第三步
1.树 : 它是n个节点的集合,满足的条件
[1]只有一个根节点
[2]其它节点可以看成是多颗子树
2.树的高度 : 节点层数的最大值
3.树叶节点 : 没有子节点
4.二叉树 : 每个节点最多两个子节点
5.完全二叉树
(1)定义 : 只有最下面两层有度数小于2的节点,且最下面一层的叶节点在最左边
(2)特点 : 完全二叉树的编号是连续的[根节点编号为1,从上到下,从左到右]
(3)性质 : 对序号为k的节点
[1]左孩子存在的条件 2*k <= n ,存在其左孩子序号为2*k
[2]右孩子存在的条件 2*k + 1 <= n,存在其右孩子序号为2*k + 1
6.二叉树遍历
(1)前序遍历 : 根节点,左子树,右子树 [根,左,右] (递归)
(2)中序遍历 : 左子树,根节点,右子树 [左,根,右] (递归)
(3)后序遍历 : 左子树,右子树,根节点 [左,右,根] (递归)
(4)层次遍历 : 从根节点开始,一层一层的遍历 (非递归)
二 完全二叉树
(1)二叉树节点类型
typedef struct bnode
{
DATATYPE data;
struct bnode *lchild;//记录左孩子地址
struct bnode *rchild;//记录右孩子地址
}btree_t;
(2)完全二叉树创建
注意:二叉树的创建没有统一的算法,需要根据其特性创建对应的二叉树
#define N 6
// 0 1 2 3 4 5 6
char buf[] = {-1,'A','B','C','D','E','F'};
btree_t *malloc_bnode(DATATYPE data)
{
btree_t *tree;
tree = (btree_t *)malloc(sizeof(btree_t));
tree->data = data;
tree->lchild = NULL;
tree->rchild = NULL;
return tree;
}:
btree_t *create_binarytree(char buf[],int num)
{
btree_t *root;
root = malloc_bnode(buf[num]);
//判断左孩子是否存在,存在则创建左孩子
if(2 * num <= N)
{
root->lchild = create_binarytree(buf,2 * num);
}
//判断右孩子是否存在,存在则创建右孩子
if(2 * num + 1 <= N)
{
root->rchild = create_binarytree(buf,2 * num + 1);
}
return root;
}
分析过程:
create_binaryteee(buf,1)
|
root = malloc_bnode(buf[1]);
if(2 * 1 <= 6)
root->lchild = create_binaryteee(buf,2);
|
root = malloc_bnode(buf[2]);
if(2 * 2 <= 6)
root->lchild = create_binaryteee(buf,4);
|
root = malloc_bnode(buf[4]);
if(2 * 4 <= 6)
...
if(2 * 4 + 1 <= 6)
...
return root;
if(2 * 2 + 1 <= 6)
root->rchild = create_binaryteee(buf,5);
|
root = malloc_bnode(buf[5]);
if(2 * 5 <= 6)
...
if(2 * 5 + 1 <= 6)
...
return root;
return root;
if(2 * 1 + 1 <= 6)
root->rchild = create_binaryteee(buf,3);
|
root = malloc_bnode(buf[3])
if(2 * 3 <= 6)
root->lchild = create_binaryteee(buf,6);
|
root = malloc_bnode(buf[6]);
if(2 * 6)
...
if(2 * 6 + 1)
...
return root;
if(2 * 3 + 1 <= 6)
...
return root;
return root;
三 二叉树的层次遍历
核心思想:使用队列技术
[1]创建一个队列
[2]将根节点进队
[3]判断队列是否为空
[4]temp = 出队
[5]打印temp->data的值
[6]判断出队节点的左孩子是否存在,如果存在则将其左孩子进队
[7]判断出队节点的右孩子是否存在, 如果存在则将其右孩子进队
[8]继续第三步
int NoOrder(btree_t *root)
{
btree_t *temp;
LinkQueue *q = create_empty_linkqueue();
enter_linkqueue(q,root);
while(!is_empty_linkqueue(q))
{
temp = delete_linkqueue(q);
printf("%c ",temp->data);
if(temp->lchild != NULL)
{
enter_linkqueue(q,temp->lchild);
}
if(temp->rchild != NULL)
{
enter_linkqueue(q,temp->rchild);
}
}
printf("\n");
return;
}
代码如下:
head.h:
#ifndef _HEAD_H_
typedef char DATATYPE1;
typedef struct bnode
{
DATATYPE1 data;
struct bnode *lchild;
struct bnode *rchild;
}btree_t;
typedef btree_t * DATATYPE;//DATATYPE <=>btree_t *
//数据节点类型
typedef struct node
{
DATATYPE data;
struct node *next;
}LinkNode;
//队列/
typedef struct
{
LinkNode *front;
LinkNode *rear;
}LinkQueue;
extern LinkQueue *create_empty_linkqueue();
extern int is_empty_linkqueue(LinkQueue *q);
extern int enter_linkqueue(LinkQueue *q,DATATYPE data);
extern DATATYPE delete_linkqueue(LinkQueue *q);
#endif
linkqueue.c
#include <stdio.h>
#include <stdlib.h>
#include "head.h"
LinkQueue *create_empty_linkqueue()
{
LinkNode *head;
LinkQueue *q;
head = (LinkNode *)malloc(sizeof(LinkNode));
head->next = NULL;
q = (LinkQueue *)malloc(sizeof(LinkQueue));
q->front = q->rear = head;
return q;
}
int is_empty_linkqueue(LinkQueue *q)
{
return q->front == q->rear ? 1 : 0;
}
int enter_linkqueue(LinkQueue *q,DATATYPE data)
{
LinkNode *temp;
temp = (LinkNode *)malloc(sizeof(LinkNode));
temp->data = data;
temp->next = NULL;
q->rear->next = temp;
q->rear = temp;
return 0;
}
DATATYPE delete_linkqueue(LinkQueue *q)
{
LinkNode *temp;
temp = q->front;
q->front = temp->next;
free(temp);
return q->front->data;
}
binarytree.c
#include <stdio.h>
#include <stdlib.h>
#include "head.h"
#define N 6
btree_t *malloc_bnode(DATATYPE1 data)
{
btree_t *tree;
tree = (btree_t *)malloc(sizeof(btree_t));
tree->data = data;
tree->lchild = tree->rchild = NULL;
return tree;
}
btree_t *create_binarytree(char buf[],int num)
{
btree_t *root;
root = malloc_bnode(buf[num]);
if(2 * num <= N){
root->lchild = create_binarytree(buf,2 * num);
}
if(2 * num + 1 <= N){
root->rchild = create_binarytree(buf,2 * num + 1);
}
return root;
}
void PreOrder(btree_t *root)
{
if(root == NULL)
return;
printf("%c ",root->data);
PreOrder(root->lchild);
PreOrder(root->rchild);
return;
}
void InOrder(btree_t *root)
{
if(root == NULL)
return;
PreOrder(root->lchild);
printf("%c ",root->data);
PreOrder(root->rchild);
return;
}
void PostOrder(btree_t *root)
{
if(root == NULL)
return;
PreOrder(root->lchild);
PreOrder(root->rchild);
printf("%c ",root->data);
return;
}
void NoOrder(btree_t *root)
{
btree_t *temp;
LinkQueue *q = create_empty_linkqueue();
enter_linkqueue(q,root);
while(!is_empty_linkqueue(q))
{
temp = delete_linkqueue(q);
printf("%c ",temp->data);
if(temp->lchild != NULL)
{
enter_linkqueue(q,temp->lchild);
}
if(temp->rchild != NULL)
{
enter_linkqueue(q,temp->rchild);
}
}
printf("\n");
return;
}
int main(int argc, const char *argv[])
{
char buf[] = {-1,'A','B','C','D','E','F'};
btree_t *root;
root = create_binarytree(buf,1);
PreOrder(root);
printf("\n");
InOrder(root);
printf("\n");
PostOrder(root);
printf("\n");
NoOrder(root);
printf("\n");
return 0;
}