【知识点】树初步
树的概念
一个父结点引出一个或多个子结点的数据结构叫做树。
没有子节点的节点也被称为叶子结点。
一个结点的子结点个数称为该结点的度。
所有结点中最大的度称为树的度。
层数:根结点为第一层,以此类推。
从根结点开始到指定结点的层数,称为深度。
从一个结点到离它最远的叶子结点的层数称为该结点的高度。
二叉树
每个结点最多有两个子结点。
空二叉树:没有任何结点。
单结点树:只有一个结点。
左斜树、右斜树:每个结点只可能有左子结点或右子结点。
满二叉树:除了叶子结点,都有左右两个子结点。
完全二叉树:除了最后一层可以为空,其余结点必须填满。叶子结点全部靠左排列。
树的存储方式
数组存储
char a[100] = '\0abcdefg';
声明一个二叉树,根结点为1号。
索引index>1时,其父结点为i/2号。
2*索引index<=1时,有左子结点2*index,否则无左子结点。同理,右子结点为2*index+1.
要求该树尽可能是完全二叉树,否则会有空间浪费。
链式存储
typedef struct TreeNode{
char data;
struct TreeNode *LChild, *RChild;
} *Node;
声明一个二叉树结点结构。
#include <iostream>
using namespace std;
typedef struct TreeNode{
char data;
struct TreeNode *LChild, *RChild;
} *Node;
Node CreateNode(char c){
Node NewNode = new TreeNode;
NewNode->data = c;
NewNode->LChild = NewNode->RChild = NULL;
return NewNode;
}
int main(){
Node a = CreateNode('A');
a->LChild = CreateNode('B');
a->RChild = CreateNode('C');
a->LChild->LChild = CreateNode('D');
a->LChild->RChild = CreateNode('E');
a->RChild->LChild = CreateNode('F');
a->RChild->RChild = CreateNode('G');
return 0;
}
这段代码以链式存储方式搭建了刚才的数组型的树,存入了ABCDEFG。
树的遍历
前序遍历
最先访问根结点,其次是左子树,最后是右子树。
#include <iostream>
using namespace std;
typedef struct TreeNode{
char data;
struct TreeNode *LChild, *RChild;
} *Node;
Node CreateNode(char c){
Node NewNode = new TreeNode;
NewNode->data = c;
NewNode->LChild = NewNode->RChild = NULL;
return NewNode;
}
void print(Node now){
if(now == NULL) return;
printf("%c",now->data);
print(now->LChild);
print(now->RChild);
return;
}
int main(){
Node a = CreateNode('1');
a->LChild = CreateNode('2');
a->RChild = CreateNode('3');
a->LChild->LChild = CreateNode('4');
a->LChild->RChild = CreateNode('5');
a->RChild->LChild = CreateNode('6');
a->RChild->RChild = CreateNode('7');
print(a);
return 0;
}
输出结果为
1245367
中序遍历
类似地,先访问左子树,再打印数据,再访问右子树。
将上段代码中print()函数改为:
void print(Node now){
if(now == NULL) return;
print(now->LChild);
printf("%c",now->data);
print(now->RChild);
return;
}
输出结果为
4251637
后序遍历
先访问左子树,再访问右子树,最后打印。
将上段代码中print()函数改为:
void print(Node now){
if(now == NULL) return;
print(now->LChild);
print(now->RChild);
printf("%c",now->data);
return;
}
输出结果为
4526731
层序遍历
使用队列进行层序遍历(也可使用数组,整体思想一致),即按照第一层从左到右,第二层从左到右……最后一层从左到右的顺序遍历树。
使用队列的方法是:如果队首元素有左子结点,左子结点入队;如果队首元素有右子结点,右子结点入队;队首元素出队。
#include <iostream>
using namespace std;
typedef struct TreeNode{
char data;
struct TreeNode *LChild, *RChild;
} *Node;
Node CreateNode(char c){
Node NewNode = new TreeNode;
NewNode->data = c;
NewNode->LChild = NewNode->RChild = NULL;
return NewNode;
}
Node line[100];
long long line_head = 0,line_tail = 1;
int main(){
Node a = CreateNode('1');
a->LChild = CreateNode('2');
a->RChild = CreateNode('3');
a->LChild->LChild = CreateNode('4');
a->LChild->RChild = CreateNode('5');
a->RChild->LChild = CreateNode('6');
a->RChild->RChild = CreateNode('7');
line[0] = a;
while(line_head!=line_tail){
if(line[line_head]->LChild != NULL)
line[line_tail++] = line[line_head]->LChild;
if(line[line_head]->RChild != NULL)
line[line_tail++] = line[line_head]->RChild;
printf("%c",line[line_head]->data);
delete line[line_head++];
}
return 0;
}
这段代码实现了层序遍历同时释放内存。
输出结果为
1234567