树结构
树最上面的节点叫做根节点,可以代表整棵树。
直接相连的节点间存在父子关系,靠近根节点的叫做父节点,另一个叫做子节点,任何节点最多只有一个父节点。
二叉树
每个节点最多只有两个子节点,这种树叫做二叉树。是最简单的树。
二叉树任何一个节点都可以看作是一棵二叉树的根节点,它和它下面所有的节点构成了一棵二叉树。
节点的左子节点叫做左子树,右节点叫做右子树。
任何二叉树都可以分为三个部分,根节点,左子树,右子树。
遍历树的过程中,一定首先遍历左子树,然后遍历右子树
根据处理根节点的时机不同,可以把树的遍历分为三种
首先处理根节点的遍历叫前序遍历
最后处理根节点的遍历叫后序遍历
中间处理根节点的遍历叫中序遍历
以下代码实现对二叉树数据结构的操作:
struct node;
typedef struct{
struct node *p_node;
}tree;
typedef struct node{
int num;
tree left;
tree right;
}node;
void tree_init(tree* p_tree){
p_tree->p_node = NULL;
}
//树的清理函数
void tree_deinit(tree* p_tree){
if(p_tree->p_node == NULL){
return ;
}
tree_deinit(&(p_tree->p_node->left));
tree_deinit(&(p_tree->p_node->right));
free(p_tree->p_node);
p_tree->p_node = NULL;
}
//在有序二叉树里查找某个数字所在位置的函数
tree* tree_search(const tree* p_tree,int value){
if(p_tree->p_node == NULL)
return (tree*)p_tree;
if(p_tree->p_node->num > value)
return tree_search(&(p_tree->p_node->left),value);
else if(p_tree->p_node->num < value)
return tree_search(&(p_tree->p_node->right),value);
else {
return (tree*)p_tree;
}
}
//在有序二叉树里加入新节点的函数
int tree_insert(tree* p_tree,int value){
tree* p_tmp = tree_search(p_tree,value);
if(p_tmp->p_node) return 0;
node* p_node = (node*)malloc(sizeof(node));
if(!p_node) return 0;
p_node->num = value;
p_node->left.p_node = NULL;
p_node->right.p_node = NULL;
p_tmp->p_node = p_node;
return 1;
}
//以中序遍历的方式处理有序二叉树里所有的数字的函数
void tree_miter(const tree* p_tree,void (*p_func)(int)){
if(!(p_tree->p_node)){
return ;
}
tree_miter(&(p_tree->p_node->left),p_func);
p_func(p_tree->p_node->num);
tree_miter(&(p_tree->p_node->right),p_func);
}
//删除二叉树的元素
int tree_remove(tree* p_tree,int value){
node *p_node = NULL;
tree* p_temp = tree_search(p_tree,value);
if(p_temp->p_node == NULL) return 0;
p_node = p_temp->p_node;
if((p_node->left.p_node == NULL) && (p_node->right.p_node == NULL)){
p_temp->p_node = NULL;
}
else if(p_node->left.p_node == NULL){
p_temp->p_node = p_node->right.p_node;
}
else if(p_node->right.p_node == NULL){
p_temp->p_node = p_node->left.p_node;
}
else{
tree* p_temp1 = tree_search(&(p_node->left),p_node->right.p_node->num);
p_temp1->p_node = p_node->right.p_node;
p_temp->p_node = p_node->left.p_node;
}
free(p_node);
p_node = NULL;
return 1;
}
总结
在上述的概念中提到,一棵二叉树分为三个部分,根节点,左子树,右子树。现在我们用node结构体代表一个二叉树中的根节点部分,用tree结构体代表子树部分。这样去思考对处理问题非常有帮助。可以避免使用复杂的二级指针。