数据与结构:树(一)
二叉搜索树(一)
实现方法:栈+树
实现功能:清空一棵树,插入特定元素,删除节点,遍历一棵树
重要例程:
插入元素
递归插入
Tree Insert_1(type val, Tree tree){
if(tree==NULL){
tree=(Tree)malloc(sizeof(struct TreeNode));
if(!tree){
exit(0);
}else{
tree->val=val;
tree->left=tree->right=NULL;
}
}
else if(val<tree->val){
tree->left=Insert_1(val,tree->left);
}
else if(val>tree->val){
tree->right=Insert_1(val,tree->right);
}
}
非递归插入
Tree Insert_2(type val, Tree tree){
Tree node = (Tree)malloc(sizeof(struct TreeNode));
if (node == NULL) {
exit(-1);
}
node->val = val;
node->left = node->right = NULL;
if (tree == NULL) {
tree = (Tree)malloc(sizeof(struct TreeNode));
if (tree == NULL) {
exit(-1);
}
tree = node;
}
else{
while (tree!=NULL)
{
if(val<tree->val){
if(tree->left==NULL){
tree->left=node;
return tree;
}else{
tree=tree->left;
}
}
else if(val>tree->val){
if(tree->right==NULL){
tree->right=node;
}else{
tree=tree->right;
}
}
}
}
}
关键点: 左边的节点值都比根节点小,右边的节点值都比根节点大
删除节点
1.相关的查找过程准备
查找前件
Position Find_prev(const type val, const Tree tree){
if(tree==NULL){
return;
}
if((tree->left!=NULL && tree->left->val==val)||(tree->right!=NULL && tree->right->val==val)){
return tree;
}
if(val<tree->val){
return Find_prev(val,tree->left);
}
if(val>tree->val){
return Find_prev(val,tree->right);
}
}
查找元素
Position Find(const type val, const Tree tree){
if(tree==NULL){
return;
}
if(val==tree->val){
return tree;
}
if(val<tree->val){
Find(val,tree->left);
}
if(val>tree->val){
Find(val,tree->right);
}
}
查找最小值
-
递归查找
Position FindMin_1(const Tree tree){ if(tree==NULL){ return; } if(tree->left==NULL){ return tree; } else{ return FindMin_1(tree->left); } }
-
非递归查找
Position FindMin_2(const Tree tree){ if(tree==NULL){ return; } Tree tmp=(Tree)malloc(sizeof(struct TreeNode)); tmp=tree; while (tmp->left!=NULL) { tmp=tmp->left; } return tmp; }
查找最大值
-
递归查找
Position FindMax_1(const Tree tree){ if (tree == NULL) { return NULL; } if (tree->right == NULL) { return tree; } else{ return FindMax_1(tree->right); } }
-
非递归查找
Position FindMax_2(const Tree tree){ if (tree == NULL) { return NULL; } Tree temp = (Tree)malloc(sizeof(struct TreeNode)); temp = tree; while (temp->right != NULL) { temp = temp->right; } return temp; }
删除
-
如果节点是叶子节点: 直接删除
-
如果节点有1个儿子,可以调节其父节点指针
-
具有2个儿子,用其右子树最小的数据代替该节点(右子树最小节点肯定没有左节点),并调整指针
Tree Delete(type val, Tree tree){ if(tree==NULL){ exit(0); } Tree cur_node=Find(val,tree); Tree prev_node=Find_prev(val,tree); if(cur_node->left==NULL && cur_node->right==NULL){ Tree tmp=cur_node; (cur_node->val < prev_node->val)?(prev_node->left=NULL):(prev_node->right=NULL); free(tmp); } else if(cur_node->left&&cur_node->right){ Tree tmp=cur_node; Tree min_node=FindMin_1(cur_node->right); Tree min_prev=Find_prev(min_node->val,cur_node->right); if(min_node->right==NULL){ cur_node->val=min_node->val; min_prev->left=NULL; } else{ cur_node->val=min_node->val; min_prev->left=min_node->right; min_node->left=NULL; } free(tmp); } else{ Tree tmp=cur_node; if(cur_node->left==NULL){ cur_node=cur_node->right; } else if(cur_node->right==NULL){ cur_node=cur_node->left; } free(tmp); } }
遍历
递归遍历
//前序
void pre_Traverse_1(const Tree tree) {
if (tree != NULL) {
printf("%-2d", tree->val);
pre_Traverse_1(tree->left);
pre_Traverse_1(tree->right);
}
}
//中序
void in_Traverse_1(const Tree tree) {
if (tree != NULL) {
in_Traverse_1(tree->left);
printf("%-2d", tree->val);
in_Traverse_1(tree->right);
}
}
//后序
void post_Traverse_1(const Tree tree) {
if (tree != NULL) {
post_Traverse_1(tree->left);
post_Traverse_1(tree->right);
printf("%-2d", tree->val);
}
}
非递归遍历
void pre_Traverse_2(const Tree tree, stack P) {
Tree temp = (Tree)malloc(sizeof(struct TreeNode));
temp = tree;
if (temp == NULL) {
return;
}
while (!isEmpty(P) || temp)
{
if (temp) {
printf("%-2d", temp->val);
push(P, temp);
temp = temp->left;
}
else
{
temp = top(P);
pop(P);
temp = temp->right;
}
}
}
void in_Traverse_2(Tree tree, stack P) {
Tree temp = (Tree)malloc(sizeof(struct TreeNode));
temp = tree;
while (!isEmpty(P) || temp)
{
if (temp) {
push(P, temp);
temp = temp->left;
}
else
{
temp = top(P);
pop(P);
printf("%-2d", temp->val);
temp = temp->right;
}
}
}
关于非递归遍历,以及二叉搜索树别的内容,会在下一篇博客给出.