• 数据与结构:树(一)


    二叉搜索树(一)

    实现方法:栈+树

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

    重要例程:

    插入元素

    递归插入

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

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

  • 相关阅读:
    数据库存储过程
    asp.net类中公共类DBHelp
    asp.net Cookie的用法实例
    使用SandCastle创建.Net帮助文档
    DotNetNuke(DNN)如何升级到DNN 4.9.3
    两个VS的文档工具
    SunBlogNuke.net logo设计
    自动化测试网站
    Debugging DLL Projects
    .NET 下自动生成UML图
  • 原文地址:https://www.cnblogs.com/oasisyang/p/13193605.html
Copyright © 2020-2023  润新知