【问题标题】:Sorted List insertion keeps creating new head?排序列表插入不断创造新的头?
【发布时间】:2014-04-18 18:00:21
【问题描述】:

每次我想在列表中插入一个新节点时,它都会创建一个新的头,第一次它应该这样做,但第二次它应该将新节点附加到前一个节点。每当我插入此代码时,它都会不断创建一个新的头部。为什么之前插入的head没有保存?

static class TreeNode{
    int frequency;
    boolean isLeftChild;
    TreeNode parent;
    TreeNode next;

    /**
     * TreeNode class constructor to initialize the variables and also
     * takes a frequency as the parameter.
     * @param f Frequency of a certain character.
     */
    TreeNode(int f){
        frequency = f;
        isLeftChild = true;
        parent = null;
        next = null;
    }
}

// Class used to store information for the linked list.
static class List{
    TreeNode head;
    int numItems; // number of nodes in the list

    List(){
        head = null;
        numItems = 0;
        // initialize head and numItems
    }

    /**
     * Inserts a node into the TreeNode linked list according to its frequencies
     * position as it will be in a SORTED list.
     * @param freq Frequency of a specific character.
     * @return Returns the new TreeNode object that has been inserted.
     */
    TreeNode insert(int freq){
        TreeNode previous, current, newNode;
        int newFreq = freq;
        numItems++;

        previous = null;
        current = head;
        while((current != null) && (Integer.valueOf(newFreq).compareTo(Integer.valueOf(current.frequency)) > 0 )){
            previous = current;
            current = current.next;
        }
        if(previous == null){
            head = new TreeNode(newFreq);
            return head;

        }
        else{
            newNode = new TreeNode(newFreq);
            previous.next = newNode;
            return newNode;
        }

    }

【问题讨论】:

  • 为什么从不设置新节点的next指针?
  • 如果您尝试插入低于当前头部频率的内容会怎样?
  • 我想我可以很好地猜到这里出了什么问题。您能告诉我您要插入哪些值吗?
  • @liangricha 我正在为每个 TreeNode 对象插入不同的频率。只要频率大于 0,它就会被插入到列表中。它也是使用排序列表插入方法,使得链表上的头部成为最小值。
  • 您插入了哪些频率导致了错误?

标签: java tree linked-list sortedlist


【解决方案1】:

如果头部应该只创建一次,那么这就是构造函数的用途!

List() {
    // initialize head here
    head = new Node();
    head.next = head;
    head.previous = head;
}

另外,我认为您需要多考虑一下您希望列表节点的外观。我是否正确理解您正在尝试创建一个双向链接的排序列表?如果是这样,如果它的节点包含Comparabe 类型的数据对象,它可能最有用,这样您就可以将列表重用于其他目的。 (更棒的方法是将其数据类型设为通用 Comparable<T>。)

最后,如果您想在列表中存储字母的频率,那么数据类型将需要有两个字段,一个用于字母的频率,一个用于计数的字母。您必须决定要使用哪两个进行排序:字符或频率。我期待这个角色。

不管怎样,在开始编码之前,先试着画出你想做的事情。

【讨论】:

  • 是的,但是在我的主程序中,当我创建列表时,头部应该为空,然后我插入的第一个节点将成为头部。问题是在我插入下一个节点之后,我无法弄清楚为什么它没有将指针设置为头部。所以第一个 TreeNode 将 = head 并且 head.next 应该是第二个 TreeNode。
  • @user3001301 为什么要先为空?我认为这会使事情不必要地复杂化。我添加了一些代码来展示头部最初是如何成为它自己的下一个和上一个元素的。
  • 如果您注意到我正在使用我自己的 TreeNode 对象节点,这就是它以这种方式编码的原因。 TreeNode 对象稍后将用于构造树,这就是我首先使用树的原因。
  • 一个树节点有一个父节点和一个子节点。双向链表有一个前一个指针和一个下一个指针。它们是两种不同的东西。尝试为一个目的使用一个类。这使您的代码更易于理解和创建。所以如果你以后想构造一棵树,到时候写一个方法来完成从列表到树的转换。
【解决方案2】:

让我试一试:

假设您首先按顺序插入频率为 5 和 4 的 TreeNodes。正如您所说,第一次插入将按预期进行。当您尝试插入频率为 4 的 TreeNode 时,while(...) 将立即被绕过,这意味着当前仍然是频率为 5 的 TreeNode,而之前的仍然是 null。根据您的代码,这将导致链接列表创建一个新的头,并覆盖以前的。

简而言之,如果您插入的具有频率的 TreeNode 小于头部的频率,则您没有正确分配。为了纠正这个问题,应该在你的 while 循环之后添加这样的东西:

if(current == head) {
  newNode = new TreeNode(newFreq);
  newNode.next = head;
  head = newNode;
}

此外,如果您的 if/else 语句在“else”部分中,您没有分配 newNode 的“下一个”字段,因此应添加此语句:

newNode.next = current;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-21
    • 2018-04-02
    • 2021-05-02
    • 1970-01-01
    • 2016-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多