Java 重复值情况下的插入排序,双链表ADT
在输入尾部出现重复值的情况下,我的插入排序有一个奇怪的问题。我得到的最基本的情况是数组{A,A,A}有问题。由于我在跟踪初始索引,所以我能够判断出这是不正确的排序,从而存储了不正确的索引,从而丢失了值。以下是插入排序的实现:Java 重复值情况下的插入排序,双链表ADT,java,algorithm,sorting,Java,Algorithm,Sorting,在输入尾部出现重复值的情况下,我的插入排序有一个奇怪的问题。我得到的最基本的情况是数组{A,A,A}有问题。由于我在跟踪初始索引,所以我能够判断出这是不正确的排序,从而存储了不正确的索引,从而丢失了值。以下是插入排序的实现: List A = new List(); String[] inputArray = {"A","A","A","A"}; String key; int i, j; //begin insertion sort for (j
List A = new List();
String[] inputArray = {"A","A","A","A"};
String key;
int i, j;
//begin insertion sort
for (j = 1; j < inputArray.length; j++) {
i = j - 1;
key = inputArray[j];
while (i >= 0) {
if (key.compareTo(inputArray[i]) > 0) {
break;
}
inputArray[i+1] = inputArray[i];
A.moveTo(i+1);
//make sure we aren't trying to insert before first node
if (i > 0) { A.insertBefore(i); }
else { A.prepend(i); }
//remove node at cursor
A.delete();
i--;
System.out.println("inner: "+ A);
}
inputArray[i+1] = key;
A.moveTo(i+1);
if (i >= 0) { A.insertBefore(j); System.out.println("insert: " + A);}
else { A.prepend(j); System.out.println("prepend: " + A);}
System.out.println("current cursor:" + A.getIndex());
A.delete();
System.out.println("outer: " + A);
}
以下是List类的相关部分:
class List {
private class Node {
//Fields
int data;
Node next, previous;
//Constructor
Node(int data) {
this.data = data;
next = null;
previous = null;
}
public String toString() {
return String.valueOf(data);
}
}
//Fields
private Node frontNode, backNode, cursorNode;
private int totalSize, cursorPosition;
//Constructor
List() {
frontNode = backNode = cursorNode = null;
totalSize = 0;
cursorPosition = -1;
}
//length(): Returns number of elements in this list
int length() {
return totalSize;
}
//getIndex: Returns the index of the cursor element in this list, or
//returns -1 if the cursor element is undefined.
int getIndex() {
return cursorPosition;
}
//prepend(int data): Inserts new element before front element in this List.
void prepend(int data) {
Node node = new Node(data);
if (this.length() == 0) {
frontNode = backNode = node;
} else {
frontNode.previous = node;
node.next = frontNode;
frontNode = node;
}
totalSize++;
if (cursorPosition != -1) {
cursorPosition++;
}
}
//insertBefore(int data): Inserts new element before cursor element in this
// List. Pre: length()>0, getIndex()>=0
void insertBefore(int data) {
Node node = new Node(data);
if (this.length() > 0 && this.getIndex() >= 0) {
node.previous = cursorNode.previous;
node.next = cursorNode;
cursorNode.previous.next = node;
cursorNode.previous = node;
totalSize++;
cursorPosition++;
} else if (this.length() <= 0) {
throw new RuntimeException("Error: insertBefore called on empty list");
} else {
throw new RuntimeException("Error: insertBefore called without cursor set");
}
}
类列表{
私有类节点{
//田地
int数据;
节点next,previous;
//建造师
节点(int数据){
这个数据=数据;
next=null;
previous=null;
}
公共字符串toString(){
返回字符串.valueOf(数据);
}
}
//田地
私有节点frontNode、backNode、cursorNode;
私有整数totalSize,游标位置;
//建造师
列表(){
frontNode=backNode=cursorNode=null;
totalSize=0;
光标位置=-1;
}
//length():返回此列表中的元素数
int-length(){
返回总大小;
}
//getIndex:返回此列表中游标元素的索引,或
//如果游标元素未定义,则返回-1。
int getIndex(){
返回光标位置;
}
//前置(整型数据):在此列表中的前置元素之前插入新元素。
无效预结束(整型数据){
节点=新节点(数据);
if(this.length()==0){
前节点=后节点=节点;
}否则{
frontNode.previous=节点;
node.next=frontNode;
frontNode=节点;
}
totalSize++;
如果(光标位置!=-1){
光标定位++;
}
}
//insertBefore(int数据):在该表中的游标元素之前插入新元素
//List.Pre:length()>0,getIndex()>=0
void insertBefore(int数据){
节点=新节点(数据);
if(this.length()>0&&this.getIndex()>=0){
node.previous=cursorNode.previous;
node.next=cursorNode;
cursorNode.previous.next=节点;
cursorNode.previous=节点;
totalSize++;
光标定位++;
}else if(this.length()则无需在while
循环中修改列表
for (j = 1; j < inputArray.length; j++) {
i = j - 1;
key = inputArray[j];
while (i >= 0) {
if (key.compareTo(inputArray[i]) >= 0) {
break;
}
inputArray[i+1] = inputArray[i];
i--;
}
inputArray[i+1] = key;
A.moveTo(i+1);
A.insertBefore(j); // insert 'key' in right place
A.moveTo(j+1);
A.delete(); // remove old occurrence of 'key'
}
<代码>用于(j=1;j=0){
if(key.compareTo(inputArray[i])>=0){
打破
}
输入阵列[i+1]=输入阵列[i];
我--;
}
输入阵列[i+1]=键;
A、 移动到(i+1);
A.insertBefore(j);//在正确的位置插入“key”
A.移动到(j+1);
A.delete();//删除旧出现的“key”
}
我将>
替换为=
,以使循环在键大于或等于当前元素时立即停止。这样,键将在值相等之后插入,而不是之前插入
我建议您扩展
insertBefore
以在cursorPosition==0
时开始插入。这是一个逻辑扩展,它消除了插入排序算法中的特殊情况。谢谢。我对insertBefore进行了修改,以便它可以处理边缘情况。但是,您现有的算法会导致上一次迭代时出错,因为调用A.moveTo(j)时,j与列表的长度相同。@IanFiddes我的建议是使光标位置等于长度是合法的。这仍然不起作用:(我无法使cursorPosition等于长度合法-cursorPosition基于1,长度基于0。但是,我确实将其更改为在长度为j的情况下附加j的值。但这不起作用。在第二次迭代后,值丢失,因为j不等于删除的项。@IANFIDES我编辑了我的答案。)为避免在结尾插入。请发布moveTo()
的实现,如果仍然不起作用,请发布delete()
。
for (j = 1; j < inputArray.length; j++) {
i = j - 1;
key = inputArray[j];
while (i >= 0) {
if (key.compareTo(inputArray[i]) >= 0) {
break;
}
inputArray[i+1] = inputArray[i];
i--;
}
inputArray[i+1] = key;
A.moveTo(i+1);
A.insertBefore(j); // insert 'key' in right place
A.moveTo(j+1);
A.delete(); // remove old occurrence of 'key'
}