我需要维护一个已排序的数据结构,可以从中删除和添加项目。为此,我决定选择一个链表。每个数据项都包含一个字母和一些数字,如下所示: A1480,A1488,B1297,C3119 这些需要按顺序维护。我为它编写了代码,它首先在已经排序的链表中找到需要添加新项的位置,然后将项添加到正确的位置,从而维护已排序的链表。它工作但有些项目是错位的,我不知道如何修复我的代码。我知道最后一个循环有问题,但我不确定它是什么。
public static void main(String[] args) {
list = new LinkedList<String>();
add("C3138");
add("C3119");
add("A1488");
add("A1480");
add("A1517");
add("B1297");
add("C2597");
add("B1356");
add("C9000");
add("C3517");
add("C3729");
add("C1729");
add("B1729");
}
public static void add(String value) {
// Integer value form the string passed into the method
int valueInt = getInt(value);
// If linked list is empty, add value and return from method
if (list.size() == 0) {
list.add(value);
return;
}
// Compare this item to be added to the first item
int firstNode = getInt(list.get(0));
if (list.get(0).charAt(0) > value.charAt(0)
|| (list.get(0).charAt(0) == value.charAt(0) && firstNode > valueInt)){
list.add(0, value);
return;
}
// Compare this item to the last item
int lastNode = getInt(list.get(list.size() - 1));
if (list.get(list.size() - 1).charAt(0) < value.charAt(0) ||
(list.get(list.size() - 1).charAt(0) == value.charAt(0) && lastNode < valueInt)) {
list.add(list.size(), value);
return;
}
// add the inbetween items
int i = 1;
int tempInt = getInt(list.get(i));
while ((list.get(i).charAt(0) < value.charAt(0)
|| ((list.get(i).charAt(0) == value.charAt(0)) && (valueInt < tempInt)) && i < list.size())) {
tempInt = getInt(list.get(i));
i++;
}
list.add(i, value);
}
public static int getInt(String item) {
return Integer.parseInt(item.replaceAll("\\D", ""));
}
下面这段代码给出了输出:
[A1480,A1517,A1488,B1729,B1297,B1356,C1729,C3729,C3517,C2597, C3119,C3138,C9000]
正如您所看到的,开始和结束之间的某些值放错位置,但开始和结束值都是正确的。请帮忙
答案 0 :(得分:1)
查看Why is there no SortedList in Java?
如果您的值是唯一的,则可以使用TreeSet
。通常,如果您想要一个已排序的集合,您可能不想从LinkedList开始。
答案 1 :(得分:1)
为什么不使用可比较?
滚动到底部,查看已实施的类Comparable
这是你问题的答案:
private static LinkedList<SuperRosie> list;
public static void main(String[] args) {
// TODO Auto-generated method stub
list = new LinkedList<SuperRosie>();
add("C3138");
add("C3119");
add("A1488");
add("A1480");
add("A1517");
add("B1297");
add("C2597");
add("B1356");
add("C9000");
add("C3517");
add("C3729");
add("C1729");
add("B1729");
for (int i = 0; i < list.size(); i++)
System.out.println(list.get(i).getValue());
}
private static void add(String value) {
SuperRosie myNewRs = new SuperRosie(value);
int listSize = list.size();
// If linked list is empty, add value and return from method
if (listSize == 0) {
list.add(myNewRs);
return;
}
// Compare this item to be added to the first item
SuperRosie element = list.getFirst();
if (myNewRs.compareTo(element) <= 0) {
list.addFirst(myNewRs);
return;
}else{
if(listSize == 1){
list.addLast(myNewRs);
return;
}
}
// Compare this item to the last item
element = list.getLast();
if (myNewRs.compareTo(element) >= 0) {
list.addLast(myNewRs);
return;
}else{
if(listSize == 1){
list.addFirst(myNewRs);
return;
}
}
// add the inbetween items
int compare = 0;
for (int i = 1; i < listSize; i++) {
element = list.get(i);
compare = myNewRs.compareTo(element);
if (compare <= 0) {
list.add(i, myNewRs);
break;
}
}
}
对可比较的链接列表进行排序的示例:
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
LinkedList<SuperRosie> list = new LinkedList<SuperRosie>();
list.add(new SuperRosie("C3138"));
list.add(new SuperRosie("C3119"));
list.add(new SuperRosie("A1488"));
list.add(new SuperRosie("A1480"));
list.add(new SuperRosie("A1517"));
list.add(new SuperRosie("B1297"));
list.add(new SuperRosie("C2597"));
list.add(new SuperRosie("B1356"));
list.add(new SuperRosie("C9000"));
list.add(new SuperRosie("C3517"));
list.add(new SuperRosie("C3729"));
list.add(new SuperRosie("C1729"));
list.add(new SuperRosie("B1729"));
Collections.sort(list);
for(SuperRosie rs : list)
System.out.println(rs.getValue());
}
}
SuperRosie.java 类来自Comparable
public class SuperRosie implements Comparable<SuperRosie> {
private String value;
public SuperRosie(String value) {
this.value = value;
}
public String getValue() {
return value;
}
@Override
public int compareTo(SuperRosie arg0) {
int compareFirst = this.value.charAt(0) - arg0.value.charAt(0);
return compareFirst == 0 ? (Integer.parseInt(this.value.replaceAll(
"\\D", "")) - Integer
.parseInt(arg0.value.replaceAll("\\D", ""))) : compareFirst;
}
public static Comparator<SuperRosie> FruitNameComparator = new Comparator<SuperRosie>() {
public int compare(SuperRosie rosie1, SuperRosie rosie2) {
String rosieValue1 = rosie1.value.toUpperCase();
String rosieValue2 = rosie2.value.toUpperCase();
// ascending order
return rosieValue1.compareTo(rosieValue2);
// descending order
//return rosieValue2.compareTo(rosieValue1);
}
};
}
答案 2 :(得分:1)
尝试这样做::将你的最后一个条件更改为此::
i
您目前正在做的是增加tempInt
,除非您的varInt
值小于i
,这就是为什么A1517会在A1488之前插入的原因。
您应增加tempInt
,直到i
的值小于`varInt,以便达到当前元素可以达到的最大位置。我希望我能说清楚。
工作代码Ideone link :: http://ideone.com/ZafWEO
此外,最好在访问链接列表项之前检查(i < list.size() && (list.get(i).charAt(0) < value.charAt(0) || ((list.get(i).charAt(0) == value.charAt(0)) && (valueInt > tempInt)))
的值。因此,条件应如下所示::
http://example.com/abc/Pages/default.aspx
答案 3 :(得分:1)
根据性能问题,我建议另一种性能解决方案。
private static LinkedList<String> list;
public static void main(String[] args) {
list = new LinkedList<>();
add("C3138");
add("C3119");
add("A1488");
add("A1480");
add("A1517");
add("B1297");
add("C2597");
add("B1356");
add("C9000");
add("C3517");
add("C3729");
add("C1729");
add("B1729");
for (int i = 0; i < list.size(); i++)
System.out.println(list.get(i));
}
private static void add(String value){
// don't check empty array, check to add in the first, last element.
// Each case, it works but when array has more than 1 element,
// so the above check are useless, run will cost memory, steps,....
// So don't, please do just the following
int insertIndex = 0;
for(String element : list){
if(compare(value, element) <= 0){ // or whatever compare way you want
break;
}else{
insertIndex+=1;
}
}
list.add(insertIndex, value);
}
private static int compare(String value1, String value2){
int compareFirst = value1.charAt(0) - value2.charAt(0);
return compareFirst == 0 ? (Integer.parseInt(value1.replaceAll(
"\\D", "")) - Integer
.parseInt(value2.replaceAll("\\D", ""))) : compareFirst;
}