搜索中资深排序算法工程师,要求掌握深度学习中的机器学习排序算法,比如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
前序遍历: