二叉树的概念
每个节点至多有两个孩子的树叫做二叉树
二叉树的存储结构
1 2 3 4 5
| typedef struct bTree{ char ele; struct bTree* lchild; struct bTree* rchild; }bTree;
|
二叉树节点使用结构体存储,包含数据域和指针域。指针域为分别指向左右孩子的指针
二叉树的创建
二叉树的创建方式有很多种,在这里我们根据树的先序遍历序列来创建一个二叉树
创建根节点
1
| struct bTree* root=(struct bTree*)malloc(sizeof(struct bTree));
|
树的先序序列如下,其中##代表空节点
1 2
| char *data="ABD##E##CF##G##"; int index=0;
|
树的结构为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void create_tree(bTree **root,char *data,int *index){ char ch; ch=data[*index]; (*index)++; if(ch=='#'){ (*root)=NULL; return; } (*root)=(struct bTree *)malloc(sizeof(bTree)); (*root)->ele=ch; create_tree(&(*root)->lchild,data,index); create_tree(&(*root)->rchild,data,index);
}
|
二叉树的遍历
二叉树的遍历主要包括:前序遍历,中序遍历,后序遍历和层次遍历。
前序遍历
前序遍历的顺序为:root->lchild->rchild
。先序是对于根节点而言的。对于每一个节点,先访问根节点root,再先序遍历以root的左孩子为根节点的子树,最后先序访问root的右孩子为根节点的子树。
下面是树的先序遍历过程:
对于根节点A,我们的访问顺序为:先访问A,后访问A的左部分,最后访问A的右部分。
首先我们访问A节点,遍历序列:A->
之后我们访问A的左部分,即部分2。对于部分2,仍是采用先根节点,后左节点,最后右节点的顺序进行。于是遍历顺序:A->B->D->E
最后我们访问A的右部分,先根后左,最后为右节点.得到遍历顺序:A->B->D->E->C->F->G
代码部分如下
1 2 3 4 5 6 7 8 9 10 11
| void preoder_traversal(struct bTree* root){ if(root==NULL){ return; } else{ printf("%c->",root->ele); preoder_traversal(root->lchild); preoder_traversal(root->rchild); }
}
|
代码中,我们首先判断要访问的节点是否为空,为空则函数返回,不进行节点访问。若不为空,则先打印节点数据,然后递归访问左子树,在递归访问右字数
中序遍历
中序遍历和先序遍历原理相似,其遍历顺序为:先访问左子树,后访问根节点,最后访问右子树
中序遍历代码
1 2 3 4 5 6 7 8 9 10 11 12
| void inoder_traversal(struct bTree* root){ if(root==NULL){ return; } else{ inoder_traversal(root->lchild); printf("%c->",root->ele); inoder_traversal(root->rchild); }
}
|
后序遍历
1 2 3 4 5 6 7 8 9 10 11 12
| void postoder_traversal(struct bTree* root){ if(root==NULL){ return; } else{ postoder_traversal(root->lchild); postoder_traversal(root->rchild); printf("%c->",root->ele); }
}
|
层次遍历
二叉树的层次遍历为从根子树所在层开始,按层从左往右遍历。
上面这颗树的层次遍历顺序为:A->B->C->D->E->F->G。层次遍历可以通过队列实现。
代码实现:
队列结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| typedef struct QueueNode{ struct bTree* treenode; struct QueueNode *pre; struct QueueNode *next; }QueueNode;
struct QueueNode* init_queue(){
struct QueueNode *head=(struct QueueNode*)malloc(sizeof(struct QueueNode)); head->treenode=NULL; head->next=head; head->pre=head; return head; }
void en_queue(struct bTree* treenode,struct QueueNode *head){ struct QueueNode *node=(struct QueueNode*)malloc(sizeof(struct QueueNode)); node->treenode=treenode; node->next=head; node->pre=head->pre;
head->pre->next=node; head->pre=node; }
struct QueueNode* de_queue(struct QueueNode* head){ if(head->next==head){ return NULL; } else{ struct QueueNode* tmp=head->next; head->next=head->next->next; head->next->pre=head; return tmp; }
}
|
层次遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void layer_travesal(struct QueueNode* head){
if(head->next==head){ return; } struct QueueNode* node=de_queue(head); struct bTree* treenode=node->treenode; printf("%c->",treenode->ele); if(treenode->lchild!=NULL){ en_queue(treenode->lchild,head); } if(treenode->rchild!=NULL){ en_queue(treenode->rchild,head); } layer_travesal(head); }
|