有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

重复值情况下的java插入排序,双链表ADT

在输入尾部出现重复值的情况下,我的插入排序有一个奇怪的问题。我得到的最基本的情况是数组{A,A,A}有问题。由于我在跟踪初始索引,所以我能够判断出这是不正确的排序,从而存储了不正确的索引,从而丢失了值。以下是插入排序的实现:

    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);
    }

使用本文中的println,我得到以下输出:

inner:  0 0 2 3
prepend: 1 0 0 2 3
current cursor:1
outer: 1 0 2 3 //works fine the first time
inner:  1 0 1 3
inner:  0 1 1 3
prepend: 2 0 1 1 3
current cursor:1
outer: 2 1 1 3 //deletes the wrong value? Why?
inner:  2 1 1 2
inner:  2 1 1 2
inner:  0 2 1 2
prepend: 3 0 2 1 2
current cursor:1
outer: 3 2 1 2

以下是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");
    }
}

共 (1) 个答案

  1. # 1 楼答案

    无需修改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'
    }
    

    我用>=替换了>,以使循环在键大于当前元素或等于当前元素时立即停止。这样,键将在相等值之后插入,而不是在相等值之前插入

    我建议您扩展insertBefore以在cursorPosition == 0开始时插入。这是一个逻辑扩展,它消除了插入排序算法中的特殊情况