一个特殊序列的排序问题

malligator 2009-08-13 11:20:23
一个特殊序列的排序问题
有一个关于排序的问题:
类似于在学校时的站队:在一次排好队后,老师可能是这么跟大家说的:“记住自己前面的是谁,以后按这个顺序排!”
抽象出来就是,比如有一个队列[1,2,3],在排序的时候,1和2比较可以知道1在2前面,2和3比较也可以知道2在3前面,但1和3比较是不知道结果的。

这样一来,我们的排序算法/比较器(还是不能用比较器了?)该怎么写呢?
...全文
300 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
弘石 2009-08-25
  • 打赏
  • 举报
回复
我也很惭愧,我才三个三角,还在这里瞎白活
sunnyfun888 2009-08-13
  • 打赏
  • 举报
回复
楼主的意思大概明白了:
就是:
有若干集合 A B C
其中
A={a}
B={b1, b2}
C={c1, c2}
b1,b2之间没有明确的顺序,同样c1,c2也没有明确的顺序
已知排列 A->B->C
现在要将 集合中的所有元素按上面A->B->C的顺序填回去。


那么:
可以先将ABC排序,然后再对每个集合求出其所有元素可能的排列,最后把两个结果并在一起。
bigbug9002 2009-08-13
  • 打赏
  • 举报
回复
mport java.util.*;
class Item implements Comparable<Item>{
private int i;

public Item(int i) {
super();
this.i = i;
}

public int getI() {
return i;
}

public void setI(int i) {
this.i = i;
}

@Override
public int compareTo(Item o) {
int c = i - o.i;
if (c == 1 || c == -1) {
return c;
}

return 0;
}

@Override
public String toString() {
return String.valueOf(i);
}
}
public class Sorter{
private HashMap<Item,Integer> originalList=new HashMap<Item,Integer>();
Sorter(List<Item> myList){
for(int i=0;i<myList.size();i++){
originalList.put(myList.get(i),i);
}
}
public void sort(List<Item> myList){
Collections.sort(myList,new comparator());
}
public class comparator implements Comparator<Item>{
public int compare(Item i1,Item i2){
return originalList.get(i1)-originalList.get(i2);
}
public boolean equals(Object o){
return false;
}
}
public static void main(String[] args){
Random rand=new Random();
List<Item> list = new ArrayList<Item>();
for (int i = 0; i < 10; i++) {

list.add(new Item(rand.nextInt(10)));
}

Sorter mySorter=new Sorter(list);
System.out.println("排序之前");
System.out.println(list);

Collections.shuffle(list);
for(int i=0;i<3;i++){
System.out.println(list.remove(i)+"被删除了");
}
mySorter.sort(list);
System.out.println("排序之后");
System.out.println(list);
}
}

F:\java>java Sorter
排序之前
[3, 1, 6, 3, 4, 5, 7, 5, 6, 2]
5被删除了
2被删除了
5被删除了
排序之后
[3, 1, 6, 3, 4, 7, 6]
弘石 2009-08-13
  • 打赏
  • 举报
回复
如果这个序列能像arraylist一样可以遍历的话,这不就是一个排序算法的实现吗?只不过比较时调用Items的compareTo方法而已,有什么区别?
弘石 2009-08-13
  • 打赏
  • 举报
回复
楼主也是星级的了,提的问题应该不是那么简单的问题
我觉得你最好把原始的问题详细描述一下,数据到底是以什么结果存储的?排序之后是不是有什么属性不允许改变?
malligator 2009-08-13
  • 打赏
  • 举报
回复
补充说明:

1) 为了不造成“你既然实现了Comparable了,可以直接用Arrays.sort和Collections.sort了”的误解,我把原来实现的comparable接口去掉了

2) Item中i不可访问,意思是已经提供了比较方法了。不要尝试用反射之类的方法来重写比较方法

3) 给出一个简单的实现方法:在冒泡排序的基础上再加一重循环就可以了,时间复杂度为O(N*N*N)
malligator 2009-08-13
  • 打赏
  • 举报
回复
说得太费劲了。

代码如下:
package test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Sorter {
public static void main(String[] args) {
List<Item> list = new ArrayList<Item>();
for (int i = 0; i < 10; i++) {

list.add(new Item((int) (Math.random()*12)));
}
Collections.shuffle(list);

System.out.println("排序前:" + Arrays.toString(list.toArray()));

sort(list);

System.out.println("排序后:" + Arrays.toString(list.toArray()));
}

private static void sort(List<Item> list) {
// TODO Auto-generated method stub

}
}

package test;

public class Item {
private int i;

public Item(int i) {
super();
this.i = i;
}

public int compareTo(Item o) {
int c = i - o.i;
if (c == 1 || c == -1) {
return c;
}

return 0;
}

@Override
public String toString() {
return String.valueOf(i);
}
}


如上代码,只允许在Sorter的sort方法内添加代码的限制下,如何能让sort后list有顺序?

bigbug9002 2009-08-13
  • 打赏
  • 举报
回复
你既然实现了Comparable了,可以直接用Arrays.sort和Collections.sort了
malligator 2009-08-13
  • 打赏
  • 举报
回复
有人明白bigbug9002想说的意思吗?

我的疑问:
1)为什么是TreeMap?
2)"根据元素可以从Map中求得其序号,比较序号就可以了。" + "无论如何你得有一个预设的序列吧。也就是说每一个元素都有一个唯一的序号于之对应。"
=> 原来序列就是有序的?? 我上面给出是有序的是为了说明要求啊
malligator 2009-08-13
  • 打赏
  • 举报
回复
可能表达得不是很清楚?
用代码说话:
class Item implements Comparable<Item>{
private int i;

public Item(int i) {
super();
this.i = i;
}

public int getI() {
return i;
}

public void setI(int i) {
this.i = i;
}

@Override
public int compareTo(Item o) {
int c = i - o.i;
if (c == 1 || c == -1) {
return c;
}

return 0;
}

@Override
public String toString() {
return String.valueOf(i);
}
}


那问题就是:给定一个Item的集合,如何得到一个该集合的序列,使得序列中任意元素都小于等于(compareTo返回结果小于等于零)它后面的元素。
bigbug9002 2009-08-13
  • 打赏
  • 举报
回复
无论如何你得有一个预设的序列吧。也就是说每一个元素都有一个唯一的序号于之对应。
malligator 2009-08-13
  • 打赏
  • 举报
回复
序号是根据什么得来的?
bigbug9002 2009-08-13
  • 打赏
  • 举报
回复
不对了,k为元素,value是序号.

排序时,根据元素可以从Map中求得其序号,比较序号就可以了。
bigbug9002 2009-08-13
  • 打赏
  • 举报
回复
可以用TreeMap来做。k为每一元素的编号,value为元素。
bigbug9002 2009-08-13
  • 打赏
  • 举报
回复
如果,1和3比不知道结果,是没有办法直接排序的。

除非从3开始找其前趋,再找前趋的前趋,一直到第一个。还要从3开始找其后继,再找后继的后继。
比较两个元素要遍历整个序列。太麻烦了。

malligator 2009-08-13
  • 打赏
  • 举报
回复
也就是说,不能唯一判定任一元素的前趋/后继(用链表的话)
malligator 2009-08-13
  • 打赏
  • 举报
回复
假如扩展一下,序列是[A,B1,B2,C1,C2]
这里,只知道:A <B1,A <B2,B2 <C1,B2 <C2
也就是说排序排成:[A,B2,C1,C2,B1]
或者[A,B2,B1,C1,C2]
或者[A,B1,B2,C1,C2]
或者[A,B1,B2,C2,C1]
都是可以的。

这就有点像树了
malligator 2009-08-13
  • 打赏
  • 举报
回复
假如扩展一下,序列是[A,B1,B2,C1,C2]
这里,只知道:A<B1,A<B1,B2<C1,B2<C2
也就是说排序排成:[A,B2,C1,C2,B1]
或者[A,B2,B1,C1,C2]
或者[A,B1,B2,C1,C2]
或者[A,B1,B2,C2,C1]
都是可以的。

这就有点像树了
弘石 2009-08-13
  • 打赏
  • 举报
回复
那就拿出来排序再放进去
用这样的结构排序很慢
【如鱼饮水】 2009-08-13
  • 打赏
  • 举报
回复
那随便找一个如2

知道2前面是1 后面是3

那可以循环列表找1和3
插入就好

好像双向链表
加载更多回复(14)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧