• 原创:基于二叉树的中序遍历法排序代码


    搜索中资深排序算法工程师,要求掌握深度学习中的机器学习排序算法,比如ListNet算法等等。其实,排序算法有很多,比较著名的应用,比如从海量数据中寻找出topk(k值很小)的算法,实现逻辑很简单,要求是最优算法,这里不详细说。在搜索中,返回的文档,在考虑很多因素情况下的机器学习排序……截至到2014年,google的排序,仍然没有采用机器学习排序,它的应用,更多在广告算法中。因为,在垂直搜索领域,使用lucene的edismax解析器自定义排序规则,效果可能更好。priorityQueue也可以实现排序,实现思路与topk形似。堆排序与树的中序遍历都可以实现排序。下面的代码,就是本人闲着没事儿,写的基于树的中序遍历的排序算法。可以对数字和字符串排序(字符优先,长度其次)。闲着没事,练练底层的基本功,时间长了,编码能力就提升了。

    package com.txq.binaryTree;
    /**
     * 二叉树节点
     * @author TongXueQiang
     * @version 1.0
     * @param <E> 节点属性
     */
    public class BinaryNode<E> implements Comparable<E> {
     public E data;
     public int freq;//频率
     public BinaryNode<E> leftNode;
     public BinaryNode<E> rightNode;
     
     public BinaryNode(E data){
      this.data = data;
     }

     @Override
     public int compareTo(E other) {
      //如果是数字,默认按升序排列
      if(data instanceof Integer){
       return (Integer)this.data - (Integer)other;
      }
      else if (data instanceof String) {//如果是字符串,优先按字符顺序,其次按字符串长度优先
       char []str1 = this.data.toString().toCharArray();
       char []str2 = other.toString().toCharArray();
       int i = 0,j = 0;
       while(i < str1.length && j < str2.length && str1[i] != '' && str2[j] != ''){
        if(str1[i] - str2[j] != 0){
         return str1[i] - str2[j];
        }
        i++;j++;
       }
       if(str1.length == i && str2.length == j){
        return 0;
       } else if (str1.length == i) {
        return 1;
       } else return -1;   
      }
      return 0;  
     }

     @Override
     public String toString() {
      return "BinaryNode [data=" + data + ", freq=" + freq + ", leftNode=" + leftNode + ", rightNode=" + rightNode
        + "]";
     }
     
    }

    package com.txq.binaryTree;

    import java.util.ArrayDeque;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Queue;
    import java.util.Stack;
    /**
     * 二叉树
     * @author TongXueQiang
     * @version 1.0
     * @param <E> 节点属性
     */
    public class BinaryTree<E> {
     private BinaryNode<E> root = null;
     /**
      * 向二叉树中插入数值
      * @param data
      */
     public void insert(E data){
      root = insert(root,data);
     }
     
     private BinaryNode<E> insert(BinaryNode<E> node,E data){
      if(data == null){
       return null;
      }
      if(node == null) {
       node = new BinaryNode<E>(data);   
      }
      
      if (node.compareTo(data) > 0 ) {
       node.leftNode = insert(node.leftNode,data);   
      } else if (node.compareTo(data) < 0) {
       node.rightNode = insert(node.rightNode,data);   
      } else node.freq ++;
      
      return node;
     }
     /**
      * 按层遍历
      * @return
      */
     public List<BinaryNode<E>> preErgodic(){
      List<BinaryNode<E>> result = new ArrayList<BinaryNode<E>>();
      result = preErgodic(root,result);
      return result;
     }
     
     private List<BinaryNode<E>> preErgodic(BinaryNode<E> node, List<BinaryNode<E>> result) {
      Queue<BinaryNode<E>> queue = new ArrayDeque<BinaryNode<E>>();
      if(node == null){
       return result;
      }
      if(node != null){
       queue.offer(node);
      }
      while(!queue.isEmpty()){
       BinaryNode<E> n = queue.poll();
       if(n != null){
        result.add(n);
       }
       if(n.leftNode != null){
        queue.offer(n.leftNode);
       }
       if(n.rightNode != null){
        queue.offer(n.rightNode);
       }
      }
      return result;  
     }

     /**
      * 中序遍历,默认按降序排列输出,按照二叉树的前序遍历排序算法,时间复杂度包括构建二叉树,大约为3lgn + lgn!,而快排为n*lgn,当n趋近无穷大时,此算法优于快排
      * @return
      */
     public List<BinaryNode<E>> middleErgodic(){
      List<BinaryNode<E>> result = new ArrayList<BinaryNode<E>>();
      result = middleErgodic(root,result);
      return result;
     }
     
     private List<BinaryNode<E>> middleErgodic(BinaryNode<E> node,List<BinaryNode<E>> result){  
      Stack<BinaryNode<E>> s = new Stack<BinaryNode<E>>();
      BinaryNode<E> n = node;
      while(n != null || !s.isEmpty()){
       if(n != null){
        s.push(n);
        n = n.leftNode;
       }
       if(n == null){
        n = s.pop();
        result.add(n);
        n = n.rightNode;
       }
      }
      return result;  
     }
     
     public BinaryNode<E> getRoot(){
      return root;
     }
    }

    package com.txq.binaryTree.test;

    import java.util.List;

    import org.junit.Test;

    import com.txq.binaryTree.BinaryNode;
    import com.txq.binaryTree.BinaryTree;

    public class BinaryTreeTest {


     @Test
     public void test() {
      int []nums = {8,9,5,3,12,15,7};
      String []strs = {"ab","acb","c","cefg","bdeg","bde","ab"};
      
      BinaryTree<String> tree = new BinaryTree<String>();
      for (String i:strs) {
       tree.insert(i);
      }
      //System.out.println(tree.getRoot().data);
      List<BinaryNode<String>> result = tree.middleErgodic();
      System.out.println("排序后的结果:");
      for(BinaryNode<String> node : result){
       System.out.println(node.data);
      } 
      
      System.out.println("前序遍历:");
      result = tree.preErgodic();  
      System.out.println(result);
      
     }
    }

    输出:

    排序后的结果:
    ab
    acb
    bdeg
    bde
    cefg
    c
    前序遍历:

  • 相关阅读:
    高价格快消品终端制胜的七大“法宝”
    欧美零售商的全渠道实践
    如何做好IT项目启动阶段的管理
    项目进度管理的三大软技巧
    如何建立生鲜商品的组织结构和采购渠道
    生鲜关注点和注意点
    超市基本业务介绍
    chrome开发配置(四)生成项目及配置库引用
    chrome开发配置(三)安装开发工具
    chrome开发配置(二)获取源代码
  • 原文地址:https://www.cnblogs.com/txq157/p/6165498.html
Copyright © 2020-2023  润新知