二叉树排序实际应用

工作以后,对算法接触的比较少,近期在工作中遇到了一个应用场景。这次回来之后记录下来,就当是个日记吧。
工作中的需求是这样的——电商系统中,会员系统里面有一个积分计算的场景,这个积分,要根据会员消费的金额来进行计算。而积分的规则,又跟后台管理系统的设置相关。一句话,就是积分规则不确定,有很多个梯度(不超过100个)。
例如:积分规则为:100–10,200–25,500–80,2000–600,则说明,消费100元,赠送10积分,消费200赠送25积分,消费500赠送80积分,消费500赠送80积分,消费2000赠送600积分。消费额在某及区间之内的,按照区间最小值的金额计算积分,如消费1200元,则积分为80+25 = 105积分。

这个需求并不难,因为积分规则原本可以作为一批对象,放入list中循环遍历,由消费额来判断计算出积分,而且积分规则也不算很多,遍历原本不花时间(一般的做法也是 这样)。但主要问题是,由于需求明确规定,门店对于会员的消费单有批量导入动作,也就是说,销售单的数据量将会极为庞大,而每一个销售单的金额都需要早积分规则中进行遍历,这样一来,便利的量变会变得极为庞大,十分影响性能。
那么,怎么能够将大数据量的遍历性能提高呢?普通的遍历方式肯定不行。
经过项目组的讨论,大家觉得采用二叉树的查找法来将解决。第一步将积分规则读取到内存中,构造出一颗二叉查找树(这棵树将会存在缓存中,如果积分规则表不发生改变,树将不会刷新)。构建造出的二叉查找树用于对消费额与积分规则的计算。

好了,说了那么多,上代码:

package com.myjianjian.service.practise;

/**
 * 二叉树
 */
public class BinaryTree {
    private Node root;

    public BinaryTree(int[] datas) {
        //构造一棵二叉树,这里拿int数组举例,实际上这个数据是对象
        for (int data : datas) {
            addNode(data);
        }
    }

    private void addNode(int data) {
        //往二叉树里面添加子节点,先要构造一个节点
        Node newNode = new Node(data);
        if (root == null) {
            //根节点为空,则需要把此节点当做空节点
            root = newNode;
        } else {
            //根节点不为空,则寻找插入的地方
            root.addNode(newNode);
        }

    }

    class Node{
        private Comparable data;
        private Node left;
        private Node right;

        public void addNode(Node newNode){
                if(newNode.getData().compareTo(this.data)>0){
                    if(this.right!=null){
                        this.right.addNode(newNode);
                    }else{
                        this.right = newNode;
                    }
                }else{
                    if(this.left!=null){
                        this.left.addNode(newNode);
                    }else{
                        this.left = newNode;
                    }
                }
        }

        public Node(Comparable data) {
            this.data = data;
        }

        public Comparable getData() {
            return data;
        }

        public void setData(Comparable data) {
            this.data = data;
        }

        public Node getLeft() {
            return left;
        }

        public void setLeft(Node left) {
            this.left = left;
        }

        public Node getRight() {
            return right;
        }

        public void setRight(Node right) {
            this.right = right;
        }
    }

}

这样,只要传入int[]数组,一颗排序树就构造好了,设在在缓存中,要用的时候就取出来,采用中序遍历,找到金额所在的积分区间,算出积分值即可,十分便捷。
实际上,我们认为,除了用二叉树去实现这个需求之外,还可以采用取模,取余的遍历方式去实现,反而更加简单粗暴,但是学了数据结构就要用起来,正所谓学以致用嘛

猜你喜欢

转载自blog.csdn.net/xzq19920203/article/details/88782988