数据与结构:树(一)

二叉搜索树(一)

实现方法:栈+树

实现功能:清空一棵树,插入特定元素,删除节点,遍历一棵树

重要例程:

插入元素

递归插入

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);
    }
}

查找最小值

  1. 递归查找

    Position FindMin_1(const Tree tree){
        if(tree==NULL){
            return;
        }
        if(tree->left==NULL){
            return tree;
        }
        else{
            return FindMin_1(tree->left);
        }
    }
    
  2. 非递归查找

    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;
        
    }
    

查找最大值

  1. 递归查找

    Position FindMax_1(const Tree tree){
        if (tree == NULL) {
    		return NULL;
    	}
    	if (tree->right == NULL) {
    		return tree;
    	}
    	else{
    		return FindMax_1(tree->right);
    	}
    }
    
  2. 非递归查找

    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. 如果节点有1个儿子,可以调节其父节点指针

  3. 具有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;
		}
	}
}

关于非递归遍历,以及二叉搜索树别的内容,会在下一篇博客给出.

posted @ 2020-06-26 00:31  OasisYang  阅读(112)  评论(0编辑  收藏  举报