Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:对元素进行排序_Java_Sorting - Fatal编程技术网

Java:对元素进行排序

Java:对元素进行排序,java,sorting,Java,Sorting,我知道我们通常使用。JavaDoc说它是一个修改过的mergesort 但我需要一个排序算法,可以比较每个对象和每个对象。我会有很多元素,顺序并不重要。但有些元素确实需要在特定的其他元素之后出现(不一定是连续的)。我认为(但不知道)合并排序是不够的 也许,我想要实现的甚至不是所谓的排序 我是否需要自己实施这样一个系统,或者是否存在这样一个系统 例如: Obj1, Obj2, Obj3, Obj4 以下几对的顺序无关紧要(这意味着我的比较器应该返回0): 但是!Obj4后面跟着Obj1是非常必

我知道我们通常使用。JavaDoc说它是一个修改过的mergesort

但我需要一个排序算法,可以比较每个对象和每个对象。我会有很多元素,顺序并不重要。但有些元素确实需要在特定的其他元素之后出现(不一定是连续的)。我认为(但不知道)合并排序是不够的

也许,我想要实现的甚至不是所谓的排序

我是否需要自己实施这样一个系统,或者是否存在这样一个系统


例如:

Obj1, Obj2, Obj3, Obj4
以下几对的顺序无关紧要(这意味着我的比较器应该返回0):

但是!Obj4后面跟着Obj1是非常必要的

由于有两个(*)对,这在数学上意味着Obj1==Obj4

使用mergesort可以工作吗


谢谢

如果您知道理想的排序,一个选项是添加一些可排序的值,如表示数据之间关系的整数。例如,如果项目A必须位于项目B之前,则确保其排序值小于项目B的值。然后,您可以提供一个只查看排序值的自定义比较器,并且可以使用标准排序算法。

我发现您的要求有点不清楚。然而,从我收集的信息来看,您应该能够通过提供适当的比较器来实现这一点

编辑现在您已经添加了一个示例,我认为您甚至不需要排序。假设元素X、Y和Z必须在某个元素A之后。您所要做的就是将X、Y和Z移到列表的末尾。这可以在
O(n)
时间内完成,而不是排序的
O(n logn)


或者,您可以将A移到列表的开头。

如果元素之间有顺序(即,您可以说这个比这个小),那么合并排序(以及任何排序算法)实际上会对集合进行排序

试着用形式(数学)表达你需要的最终顺序


两个元素的顺序无关紧要这一事实并不意味着比较器必须返回0。如果它们相等,它必须返回0 iif。

您已经实现了comparator(并将其传递给标准mergesort),类似于:

int compare(Object o1, Object o2) {
  if (o1 instanceOf NotMatter) {
     if (o2 instanceOf NotMatter) {
        return 0;
     }
     return -1;
  }
  if (o2 instanceOf NotMatter) {
     return 1;
  }

  // ok, now we have two important objects
  if (o1.better(o2) {
     return 1;
  }
  if (o2.better(o1) {
     return -1;
  }
  return 0;
}

听起来你有一组DAG(有向无环图)。我认为你需要对此建模,然后对每一个进行拓扑排序。一种方法:

将每个元素包装在一个包装器对象中,该包装器对象引用该对象,并具有一个用于保存对其他对象的依赖关系的列表。将所有这些包装器放在由对象id键控的哈希映射中

对于没有直接依赖关系的所有元素,发出该元素,并将其从hashMap中删除。重复此操作,直到hashmap为空

如果依赖项列表通常很长,这将是低效的。它适用于平均数量小于5的直接依赖项。如果性能是一个问题,因为执行了太多的“重复直到hashmap为空”过程,那么应该使用一个双向数据结构来表示依赖关系图,或者可能使用一个映射项列表,这些映射项在此过程上只有一个依赖关系,因此是下一个过程的强候选项

这是一个未经测试的草图:

class Obj           { String id;    }

class ObjWrapper    {
    String id;
    Obj obj;
    String[] depends; // may be null, may have null entries

    public ObjWrapper(Obj obj, String[] depends) {
        this.id = obj.id;
        this.obj = obj;
        if ( depends != null )
            this.depends = Arrays.copyOf(depends, depends.length);
    }
}

// order the objects by dependency. 
ArrayList<Obj> orderObjs(Iterable<ObjWrapper> objs)
{
    ArrayList<Obj> output = new ArrayList();
    HashMap<String, ObjWrapper> objMap = new HashMap();
    for ( ObjWrapper obj : objs )  
        objMap.put(obj.id, obj);  
    while ( !objMap.isEmpty() ) {
        Iterator<ObjWrapper> iter = objMap.values().iterator();
        while ( iter.hasNext() ) {
            ObjWrapper objWrapper = iter.next();
            if ( !hasDependencies(objWrapper, objMap) ) {
                output.add(objWrapper.obj);
                // must use iter to remove from hash, or bad things happen.
                iter.remove();  
            }
        }
    }
    return output;
}

boolean hasDependencies(ObjWrapper objWrapper, 
                        HashMap<String, ObjWrapper> objMap)
{
    if ( objWrapper.depends == null ) return false;
    for ( String depend : objWrapper.depends )   {
        if ( depend != null ) 
            if ( objMap.containsKey(depend) )
                return true;
            else
                depend = null;  // to speed up future passes
    }
    return false;
}
class Obj{String id;}
类ObjWrapper{
字符串id;
Obj-Obj;
字符串[]依赖;//可能为空,可能有空条目
公共ObjWrapper(Obj Obj,字符串[]取决于){
this.id=obj.id;
this.obj=obj;
如果(取决于!=null)
this.dependens=Arrays.copyOf(dependens,dependens.length);
}
}
//按依赖项对对象进行排序。
ArrayList orderObjs(Iterable objs)
{
ArrayList输出=新的ArrayList();
HashMap objMap=新的HashMap();
for(ObjWrapper-obj:objs)
objMap.put(obj.id,obj);
而(!objMap.isEmpty()){
迭代器iter=objMap.values().Iterator();
while(iter.hasNext()){
ObjWrapper ObjWrapper=iter.next();
if(!hasDependencies(objWrapper,objMap)){
add(objWrapper.obj);
//必须使用iter从散列中删除,否则会发生不好的事情。
iter.remove();
}
}
}
返回输出;
}
布尔hasDependencies(ObjWrapper ObjWrapper,
HashMap(objMap)
{
if(objWrapper.depends==null)返回false;
for(字符串依赖:objWrapper.depends){
如果(依赖!=null)
if(对象映射容器(依赖))
返回true;
其他的
depend=null;//以加快将来的传递
}
返回false;
}

使用比较器可以而且应该很好地实现您的自定义排序。请您通过发布一个简单(但完整)的示例来澄清您的要求?您应该进一步澄清您希望如何“排序”您的元素。您能在这里详细介绍一下用例吗?我怀疑您正在寻找“拓扑排序”,但根据您的描述很难判断。我认为您上面的推测可能是正确的:您想要的不是排序。我这样说是因为您上面定义的标识规则:(如果Obj2必须遵循Obj1,Obj4必须遵循Obj2,那么Obj1==Obj4)。无论“必须遵循”什么意思是,这与排序无关。如果排序值可以从已经存在的值快速计算,则可能不需要额外的字段。是的,这是真的!这取决于对象的工作方式以及计算该值是否花费了很长时间,等等。但这一点很好。
class Obj           { String id;    }

class ObjWrapper    {
    String id;
    Obj obj;
    String[] depends; // may be null, may have null entries

    public ObjWrapper(Obj obj, String[] depends) {
        this.id = obj.id;
        this.obj = obj;
        if ( depends != null )
            this.depends = Arrays.copyOf(depends, depends.length);
    }
}

// order the objects by dependency. 
ArrayList<Obj> orderObjs(Iterable<ObjWrapper> objs)
{
    ArrayList<Obj> output = new ArrayList();
    HashMap<String, ObjWrapper> objMap = new HashMap();
    for ( ObjWrapper obj : objs )  
        objMap.put(obj.id, obj);  
    while ( !objMap.isEmpty() ) {
        Iterator<ObjWrapper> iter = objMap.values().iterator();
        while ( iter.hasNext() ) {
            ObjWrapper objWrapper = iter.next();
            if ( !hasDependencies(objWrapper, objMap) ) {
                output.add(objWrapper.obj);
                // must use iter to remove from hash, or bad things happen.
                iter.remove();  
            }
        }
    }
    return output;
}

boolean hasDependencies(ObjWrapper objWrapper, 
                        HashMap<String, ObjWrapper> objMap)
{
    if ( objWrapper.depends == null ) return false;
    for ( String depend : objWrapper.depends )   {
        if ( depend != null ) 
            if ( objMap.containsKey(depend) )
                return true;
            else
                depend = null;  // to speed up future passes
    }
    return false;
}