我想咨询有关订购数据的算法。
每条记录都有以下属性:
示例记录。它们并不总是处于良好的数字顺序;)
分类后:
请注意,由于订单号(优先级),记录14在记录5之前。
在我的数据集中,大约有3,000条记录,通常不超过3或4级深度。
第1步:遍历记录并获取所有顶级节点(id =父ID),按订单号对其进行排序,然后将其添加到第二个列表中。
第2步:对于列表2中的每个节点,循环遍历列表1并抓取所有子节点,按顺序号对它们进行排序,然后将它们直接插入到父节点之后的列表2中。
请注意,几乎所有排序都在步骤2中进行。
这是一个贯穿始终。
答案 0 :(得分:0)
现在已经晚了,但我想我明白了:)
List<Pojo> list = Arrays.asList(
new Pojo(1,1,1),new Pojo(2,1,1),
new Pojo(3,2,1),new Pojo(4,3,1),new Pojo(5,2,3),
new Pojo(6,5,1),new Pojo(7,6,1),new Pojo(8,1,2),
new Pojo(9,9,2),new Pojo(10,9,2),new Pojo(11,9,1),
new Pojo(12,11,1),new Pojo(13,13,3),new Pojo(14,2,2)
);
首先按父级和orderNumber排序:
Collections.sort(list, (a,b) -> {
if ( a.id == a.pId && a.pId == b.pId ) return -1;
if ( b.id == b.pId && a.pId == b.pId ) return 1;
// 100000... a number bigger there largest order#
int aa = 100000 * a.pId + a.oNo;
int bb = 100000 * b.pId + b.oNo;
if ( aa > bb ) return 1;
if ( aa < bb ) return -1;
return 0;
});
然后循环前进,并且每行遍历到另一个pojo具有相同parentId的位置或其他pojo的id等于遍历pojo的parentId:
for ( int fw = 1 ; fw < list.size() ; fw ++ )
{
Pojo a = list.get(fw);
if ( a.id != a.pId )
{
for ( int bw = fw - 1 ; bw >= 0 ; bw -- )
{
Pojo b = list.get(bw);
if ( a.pId != b.pId && a.pId != b.id )
{
list.set(bw, a);
list.set(bw+1, b);
}
else
{
break;
}
}
}
}
答案 1 :(得分:0)
这是一个依赖于上面评论中提到的树遍历的解决方案。这给出了线性时间性能,随着数据集大小的增加,它将变得更加相关。
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.function.*;
public class PriorityTree {
static class Node<T extends Comparable> implements Comparable{
private T data;
private Node<T> parent;
private Collection<Node<T>> children;
BiPredicate<Node<T>,T> addNodePredicate;
UnaryOperator<T> paddingElement;
public Node(T data, Node<T> parent, Collection<Node<T>> children,BiPredicate<Node<T>,T> addNodePredicate,UnaryOperator<T> paddingElement) {
this.data = data;
this.parent = parent;
this.children = children;
this.addNodePredicate = addNodePredicate;
this.paddingElement = paddingElement;
}
public Node(T data, Node<T> parent) {
this(data,parent,new TreeSet<Node<T>>(),parent.addNodePredicate,parent.paddingElement);
}
public boolean add(T element) {
if (this.addNodePredicate.test(this,element)) {
this.children.add(new Node<T>(element, this));
return true;
} else {
for (Node<T> node : this.children) {
if(node.add(element)) return true;
}
return false;
}
}
private String print(String indent){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(indent);
stringBuilder.append(data);
stringBuilder.append("\n");
for (Node<T> node : this.children) {
stringBuilder.append(node.print(indent+" "));
}
return stringBuilder.toString();
}
@Override
public String toString() {
return print("");
}
@Override
public int compareTo(Object o) {
return this.data.compareTo(((Node<T>)o).data);
}
}
static class Pojo implements Comparable{
int id;
int parentId;
final int orderNo;
@Override
public String toString() {
return "id=["+id + "],parentId=["+parentId+"],orderNo=["+orderNo+"]";
}
public Pojo(int id, int parentId, int orderNo) {
this(orderNo);
this.parentId = parentId;
this.id = id;
}
public Pojo(int orderNo) {
this.orderNo = orderNo;
}
public int getId() {
return id;
}
public int getParentId() {
return parentId;
}
public int getOrderNo() {
return orderNo;
}
public int compareTo(Object that) {
if (that == null )return 1;
if ( that instanceof Pojo)
return Integer.compare(this.getOrderNo(),((Pojo)that).getOrderNo());
else return 1;
}
static Pojo ROOT= new Pojo(0,0,0);
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pojo pojo = (Pojo) o;
if (id != pojo.id) return false;
if (parentId != pojo.parentId) return false;
return orderNo == pojo.orderNo;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + parentId;
result = 31 * result + orderNo;
return result;
}
}
private static List<Pojo> readInObjects(String csvFile){
final List<Pojo> list = new ArrayList<Pojo>();
try{
final FileReader fileReader = new FileReader(csvFile);
final BufferedReader br = new BufferedReader(fileReader);
String line;
while (( line = br.readLine()) != null) {
final String[] valueArray = line.split(",");
final int id = Integer.parseInt(valueArray[0]);
final int parentId = Integer.parseInt(valueArray[1]);
final int orderNo = Integer.parseInt(valueArray[2]);
final Pojo pojo = new Pojo(id,parentId,orderNo);
list.add(pojo);
}
}catch (IOException e) {
e.printStackTrace();
}
return list;
}
public static void main(String[] args){
final List<Pojo> values = readInObjects("values.txt");
final Node<Pojo> tree = new Node<>(Pojo.ROOT, null, new TreeSet<>(), (pojoNode, pojo) -> pojoNode.data.getId()==0 && pojo.getId()==pojo.getParentId() ||pojoNode.data.getId() == pojo.getParentId(),(p)->new Pojo(0,p.getId(),0));
values.stream().forEach(pojo -> tree.add(pojo));
System.out.println(tree.toString());
}
}
values.txt包含以下条目
1,1,1
2,1,1
3,2,1
4,3,1
5,2,3
6,5,1
7,6,1
8,1,2
9,9,2
10,9,2
11,9,1
12,11,1
13,13,3
14,2,2
输出看起来像
id=[1],parentId=[1],orderNo=[1]
id=[2],parentId=[1],orderNo=[1]
id=[3],parentId=[2],orderNo=[1]
id=[4],parentId=[3],orderNo=[1]
id=[14],parentId=[2],orderNo=[2]
id=[5],parentId=[2],orderNo=[3]
id=[6],parentId=[5],orderNo=[1]
id=[7],parentId=[6],orderNo=[1]
id=[8],parentId=[1],orderNo=[2]
id=[9],parentId=[9],orderNo=[2]
id=[11],parentId=[9],orderNo=[1]
id=[12],parentId=[11],orderNo=[1]
id=[10],parentId=[9],orderNo=[2]
id=[13],parentId=[13],orderNo=[3]