合并排序(看似随机重复)
Merge Sorting (seemingly random duplications)
所以我的合并排序器代码有一个小错误,其中数组列表中的一些项目将被复制并扔到一个奇怪的位置
Sorted List Unsorted List
apricot gray
aqua maize
bittersweet mahogany
blue green
brick red
cornflower apricot
flesh bittersweet
gray flesh
green cornflower
lemon orchid
magenta pink
maize orange
mahogany maroon
bittersweet blue
melon yellow
orange melon
orange magenta
maroon violet
blue silver
pearl tan
periwinkle periwinkle
purple turquoise
purple thistle
olive white
purple sienna
tan lemon
turquoise pearl
brick aqua
olive brick
purple olive
purple purple
这是我编写的代码,感谢所有反馈:
ArrayList<String> a = new ArrayList<String>();
public MergeSorter(ArrayList<String> aList)
{
a = aList;
}
public void sort()
{
if (a.size() <= 1) return;
ArrayList<String> first = new ArrayList<String>();
ArrayList<String> second = new ArrayList<String>();
for (int i = 0; i < a.size()/2; i++)
first.add(a.get(i));
for (int i = a.size()/2; i < a.size(); i++)
second.add(a.get(i));
MergeSorter firstSorter = new MergeSorter(first);
MergeSorter secondSorter = new MergeSorter(second);
firstSorter.sort();
secondSorter.sort();
merge(first, second);
}
private void merge(ArrayList<String> first, ArrayList<String> second)
{
int iFirst = 0;
int iSecond = 0;
int j = 0;
while(iFirst < first.size() && iSecond < second.size())
{
if(first.get(iFirst).compareTo(second.get(iSecond)) < 0)
{
a.set(j, first.get(iFirst));
iFirst++;
}
else
{
a.set(j, second.get(iSecond));
iSecond++;
}
j++;
}
//System.arraycopy(first, iFirst, a, j, first.size() - iFirst);
for (int i = iFirst; i < first.size() - iFirst; i++)
{
a.set(j, first.get(i));
j++;
}
//System.arraycopy(second, iSecond, a, j, second.size() - iSecond);
for (int i = iSecond; i < second.size() - iSecond; i++)
{
a.set(j, second.get(i));
j++;
}
}
}
你迭代的不够远:
for (int i = iFirst; i < first.size() - iFirst; i++)
{
a.set(j, first.get(i));
j++;
}
for (int i = iSecond; i < second.size() - iSecond; i++)
{
a.set(j, second.get(i));
j++;
}
此时其中一个列表已经被完全消耗,您只需要将另一个列表的所有剩余元素复制到结果列表中即可。这意味着从 "the beginning of the end" (iFirst
) 迭代到列表的末尾 (first.size()
).
出于某种原因,您减去 iFirst
,因此并非所有值都被复制。相反,未排序的值(用于初始化排序器的值)保留在列表的末尾,其中一些将与结果列表中实际排序的部分重复。
这应该有效:
for (int i = iFirst; i < first.size(); i++)
{
a.set(j, first.get(i));
j++;
}
for (int i = iSecond; i < second.size(); i++)
{
a.set(j, second.get(i));
j++;
}
所以我的合并排序器代码有一个小错误,其中数组列表中的一些项目将被复制并扔到一个奇怪的位置
Sorted List Unsorted List
apricot gray
aqua maize
bittersweet mahogany
blue green
brick red
cornflower apricot
flesh bittersweet
gray flesh
green cornflower
lemon orchid
magenta pink
maize orange
mahogany maroon
bittersweet blue
melon yellow
orange melon
orange magenta
maroon violet
blue silver
pearl tan
periwinkle periwinkle
purple turquoise
purple thistle
olive white
purple sienna
tan lemon
turquoise pearl
brick aqua
olive brick
purple olive
purple purple
这是我编写的代码,感谢所有反馈:
ArrayList<String> a = new ArrayList<String>();
public MergeSorter(ArrayList<String> aList)
{
a = aList;
}
public void sort()
{
if (a.size() <= 1) return;
ArrayList<String> first = new ArrayList<String>();
ArrayList<String> second = new ArrayList<String>();
for (int i = 0; i < a.size()/2; i++)
first.add(a.get(i));
for (int i = a.size()/2; i < a.size(); i++)
second.add(a.get(i));
MergeSorter firstSorter = new MergeSorter(first);
MergeSorter secondSorter = new MergeSorter(second);
firstSorter.sort();
secondSorter.sort();
merge(first, second);
}
private void merge(ArrayList<String> first, ArrayList<String> second)
{
int iFirst = 0;
int iSecond = 0;
int j = 0;
while(iFirst < first.size() && iSecond < second.size())
{
if(first.get(iFirst).compareTo(second.get(iSecond)) < 0)
{
a.set(j, first.get(iFirst));
iFirst++;
}
else
{
a.set(j, second.get(iSecond));
iSecond++;
}
j++;
}
//System.arraycopy(first, iFirst, a, j, first.size() - iFirst);
for (int i = iFirst; i < first.size() - iFirst; i++)
{
a.set(j, first.get(i));
j++;
}
//System.arraycopy(second, iSecond, a, j, second.size() - iSecond);
for (int i = iSecond; i < second.size() - iSecond; i++)
{
a.set(j, second.get(i));
j++;
}
}
}
你迭代的不够远:
for (int i = iFirst; i < first.size() - iFirst; i++)
{
a.set(j, first.get(i));
j++;
}
for (int i = iSecond; i < second.size() - iSecond; i++)
{
a.set(j, second.get(i));
j++;
}
此时其中一个列表已经被完全消耗,您只需要将另一个列表的所有剩余元素复制到结果列表中即可。这意味着从 "the beginning of the end" (iFirst
) 迭代到列表的末尾 (first.size()
).
出于某种原因,您减去 iFirst
,因此并非所有值都被复制。相反,未排序的值(用于初始化排序器的值)保留在列表的末尾,其中一些将与结果列表中实际排序的部分重复。
这应该有效:
for (int i = iFirst; i < first.size(); i++)
{
a.set(j, first.get(i));
j++;
}
for (int i = iSecond; i < second.size(); i++)
{
a.set(j, second.get(i));
j++;
}