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

搜索中资深排序算法工程师,要求掌握深度学习中的机器学习排序算法,比如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] != '\0' && str2[j] != '\0'){
    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
前序遍历:

 

posted @ 2017-02-14 17:11  佟学强  阅读(782)  评论(0编辑  收藏  举报