• 数据结构


    link

    mean

    给定n个数,按照构造Binary Search Tree的方式来构造BST树,按顺序输出每一个非root结点的父节点的值。

    analyse

    构造BST树最坏情况下时间复杂度为O(n),肯定会超时。

    注意到只需要输出结点的父节点的值,不需要真的构造BST树。

    插到第i个结点时,我们在前i-1个结点中找两个数,一个是比Ai大的最小数,一个是比Ai小的最大数。

    那么Ai的父节点肯定是这两个中的一个,到底是哪一个呢,根据画图分析,可以得出是后来插入的那个。

    如下图所示:

    做法:用java里面的容器TreeMap<Integer,Integer>来存储<value,index>对,根据value值来查找,然后比较这两个数的index大小来判断谁是父节点。

    time complexity

    O(n*logn)

    code

    1. java容器实现 
    import java.io.BufferedInputStream;
    import java.util.HashMap;
    import java.util.Scanner;
    import java.util.TreeSet;
    
    public class Main{
       public static void main(String[]argv){
           Scanner in=new Scanner(new BufferedInputStream(System.in));
           while(in.hasNext()){
               int n=in.nextInt();
               TreeSet<Integer> vals=new TreeSet<>();
               HashMap<Integer,Integer> idx=new HashMap<>();
               int val=in.nextInt();
               vals.add(val);
               idx.put(val,0);
               for(int i=1;i<n;++i){
                   val=in.nextInt();
                   Integer hi=vals.higher(val), lo=vals.lower(val);
                   if(hi==null)
                       System.out.print(lo+" ");
                   else if(lo==null)
                       System.out.print(hi+" ");
                   else {
                       Integer hiIdx=idx.get(hi);
                       Integer loIdx=idx.get(lo);
                       if(hiIdx>loIdx)
                           System.out.print(hi+" ");
                       else
                           System.out.print(lo+" ");
                   }
                   vals.add(val);
                   idx.put(val,i);
               }
               System.out.println();
           }
       }
    }
    2. avl实现 
    #include<iostream> #include<cstdio> #include<set> #include<map> #include<vector> using namespace std; ; //AVL树节点信息 class TreeNode { public: TreeNode() :lson(NULL), rson(NULL), freq(), hgt() {} int data;// int hgt;//高度 unsigned int freq;//频率 TreeNode* lson;//指向左儿子的地址 TreeNode* rson;//指向右儿子的地址 }; //AVL树类的属性和方法声明 class AVLTree { private: TreeNode* root;//根节点 void insertpri(TreeNode* &node,int x,int &pre,int &aft);//插入 int height(TreeNode* node);//求树的高度 void SingRotateLeft(TreeNode* &k2);//左左情况下的旋转 void SingRotateRight(TreeNode* &k2);//右右情况下的旋转 void DoubleRotateLR(TreeNode* &k3);//左右情况下的旋转 void DoubleRotateRL(TreeNode* &k3);//右左情况下的旋转 int Max(int cmpa, int cmpb);//求最大值 public: AVLTree() :root(NULL) {} void insert(int x,int &pre,int &aft);//插入接口 }; //计算节点的高度 int AVLTree::height(TreeNode* node) { if (node != NULL) return node->hgt; ; } //求最大值 int AVLTree::Max(int cmpa, int cmpb) { return cmpa>cmpb ? cmpa : cmpb; } //左左情况下的旋转 void AVLTree::SingRotateLeft(TreeNode* &k2) { TreeNode* k1; k1 = k2->lson; k2->lson = k1->rson; k1->rson = k2; k2->hgt = Max(height(k2->lson), height(k2->rson)) + ; k1->hgt = Max(height(k1->lson), k2->hgt) + ; k2 = k1; } //右右情况下的旋转 void AVLTree::SingRotateRight(TreeNode* &k2) { TreeNode* k1; k1 = k2->rson; k2->rson = k1->lson; k1->lson = k2; k2->hgt = Max(height(k2->lson), height(k2->rson)) + ; k1->hgt = Max(height(k1->rson), k2->hgt) + ; k2 = k1; } //左右情况的旋转 void AVLTree::DoubleRotateLR(TreeNode* &k3) { SingRotateRight(k3->lson); SingRotateLeft(k3); } //右左情况的旋转 void AVLTree::DoubleRotateRL(TreeNode* &k3) { SingRotateLeft(k3->rson); SingRotateRight(k3); } //插入 void AVLTree::insertpri(TreeNode* &node, int x,int &pre,int &aft) { if (node == NULL)//如果节点为空,就在此节点处加入x信息 { node = new TreeNode(); node->data = x; return; } if (node->data>x)//如果x小于节点的值,就继续在节点的左子树中插入x { aft = node->data; insertpri(node->lson, x,pre,aft); == height(node->lson) - height(node->rson)) if (x<node->lson->data) SingRotateLeft(node); else DoubleRotateLR(node); } else if (node->data<x)//如果x大于节点的值,就继续在节点的右子树中插入x { pre = node->data; insertpri(node->rson, x,pre,aft); == height(node->rson) - height(node->lson))//如果高度之差为2的话就失去了平衡,需要旋转 if (x>node->rson->data) SingRotateRight(node); else DoubleRotateRL(node); } else ++(node->freq);//如果相等,就把频率加1 node->hgt = Max(height(node->lson), height(node->rson)) + ; } //插入接口 void AVLTree::insert(int x,int &pre,int &aft) { insertpri(root, x,pre,aft); } map<int, int> lef, rig; int n; void init() { lef.clear(); rig.clear(); } int main() { int v,pre,aft; && n) { AVLTree tree; init(); scanf("%d", &v); tree.insert(v, pre, aft); vector<int> ans; ; i < n - ; i++) { scanf("%d", &v); pre = , aft = INF; tree.insert(v, pre, aft); //printf("pre:%d,aft:%d ", pre, aft); ) { ans.push_back(aft); lef[aft] = ; } else { ans.push_back(pre); rig[pre] = ; } } ; i < ans.size() - ; i++) printf("%d ", ans[i]); printf(]); } ; }
  • 相关阅读:
    非类型模板参数(针对C++)
    继承(针对C++)
    进程中的线程共享的资源有哪些?
    关键字typename(针对C++)
    设计模式之——工厂模式
    利用多线程同步互斥来创建自己的资源锁
    SQL优化总结
    委托与泛型
    第5章 事件和数据回发机制
    jQuery权威指南_读书笔记
  • 原文地址:https://www.cnblogs.com/crazyacking/p/5513034.html
Copyright © 2020-2023  润新知