二叉树的概念
一颗二叉树是结点的一个有限集合,集合或者为空或者是由一个根结点
加上两颗分别称为左子树和右子树的二叉树组成
二叉树的特点
二叉树的左右顺序不能颠倒
每个结点最多由两颗子树,二叉树的结点度数不大于2
二叉树的组成
二叉树的表示方法
// 常用左右孩子表示法
3 typedef char Treetype;
4
5 //定义树的节点
6 typedef struct TreeNode
7 {
8 Treetype data;
9 struct TreeNode* lchild; //左孩子
10 struct TreeNode* rchild; //右孩子
11 }TreeNode;
二叉树的初始化
用头节点的指针表示一个链表类,这里用根节点的指针表示一个树,初始时树中没有任何结点,所以将根结点的指针只置为空,因为要改变根节点的取值,所以采用二级指针作为参数
13 //初始化
14 void treeInit(TreeNode** proot)
15 {
16 if(proot==NULL)
17 {
18 printf("#"); //#表示节点为空
19 return ;
20 }
21 *proot=NULL;
22 return ;
23 }
先序遍历(递归版)
//先序遍历(递归) V L R
26 void treePrior(TreeNode* root)
27 {
28 if(root==NULL)
29 {
30 printf("#");
31 return ;
32 }
33 //输出 根节点
34 printf("%c",root->data);
35 //递归遍历左子树
36 treePrior(root->lchild);
37 //递归遍历右子树
38 treePrior(root->rchild);
39 return ;
40 }
中序遍历(递归版)
//中序遍历 L V R
42 void treeCenter(TreeNode* root)
43 {
44 if(root==NULL)
45 {
46 print("#") //输出空节点
47 return ;
48 }
49 //递归遍历左子树
50 treeCenter(root->lchild);
51 //输出根节点
52 printf("%c",root->data);
50 treeCenter(root->lchild);
51 //输出根节点
52 printf("%c",root->data);
53 //递归遍历右子树
54 treeCenter(root->rchild);
55 return ;
56
57 }
后序遍历 (递归版)
//后序遍历 L R V
60 void treeLater(TreeNode* root)
61 {
62 if(root==NULL)
63 {
64 printf("#")//#表示输出空节点
65 return ;
66 }
67 //递归遍历左子树
68 treeLater(root->lchild);
69 //递归遍历右子树
70 treeLater(root->rchild);
71 //输出根节点
72 printf("%c",root->data);
73 return ;
74 }
层序遍历
层序遍历的实现需要借用队列来实现,队列(先进先出)
实现思想:
这里需要注意的是,入队列时保存的是结点的指针,所以,队列中保存的是树的结点指针类型的数据
void treeLevel(TreeNode* root)
77 {
78 if(root==NULL)
79 {
80 //空树
81 return ;
82 }
83 //定义队列
84 SeqQueue queue;
85 //初始化队列
86 SeqQueueInit(&queue);
87
88 //1根节点入队列
89 SeqQueuePush(&queue, root);
90 int ret;
91 SeqQueueType front;
92 while(1)
93 {
94 //2取队首元素,如果为空则结束
95 ret=SeqQueueTop(&queue, &front);
96 if(ret==-1)
97 {
98 //队列已空,树已经遍历完了
99 return ;
100 }
101 //3如果队首元素不为空,访问队首元素
102 print("%c",front->data);
103 //4将队首元素出队列,
104 SeqQueuePop(&queue);
105 //5如果队首元素左右孩子不为空,将左右节点的指针入队列
106 if(front->lchild!=NULL)
107 {
108 SeqQueuePush(&queue,front->lchild);
109 }
110 if(front->rchild!=NULL)
111 {
112 SeqQueuePush(&queue,front->rchild);
113 }
114 //循环2~5即可
115 }
116 return ;
117 }