【问题标题】:C++ Linked list implementation crashingC++ 链表实现崩溃
【发布时间】:2011-10-10 00:06:08
【问题描述】:

我正在尝试为数据结构类实现一个链表,但我在算法的搜索部分遇到了一些困难。

下面是有问题的代码,我尝试按照 MIT 算法介绍文本中的伪代码来实现它:

//
// Method searches and retrieves a specified node from the list
//
Node* List::getNode(unsigned position)
{
    Node* current = m_listHead;

    for(unsigned i = m_listSize-1; (current != 0) && (i != position); --i)
            current = current->next;

    return current;
}

程序中此时的头是第4个节点,其中包含int 5的值。问题似乎出在for循环的主体中,其中指向节点对象的指针被分配给了next节点。但这超出了节点的头部,因此它本质上指向内存中的某个随机位置(这是有道理的)。

在这种情况下,算法不应该移动到前一个节点而不是下一个节点吗?下面是伪代码:

LIST-SEARCH(L, k)
    x <- head
    while x != NIL and key != k
        do x <- next[x]
    return x

另外,这里是我的链表实现的头文件。为了简单起见,我还没有尝试以模板形式实现它:

#ifndef linkList_H
#define linkList_h


//
// Create an object to represent a Node in the linked list object
// (For now, the objects to be put in the list will be integers)
//
struct Node
{
    // nodes of list will be integers
    int number;
    // pointer to the next node in the linked list
    Node* next;
};


//
// Create an object to keep track of all parts in the list
//
class List
{
public:

    // Contstructor intializes all member data
    List() : m_listSize(0), m_listHead(0) {}

    // methods to return size of list and list head
    Node* getListHead() const { return m_listHead; }
    unsigned getListSize() const { return m_listSize; }

    // method for adding a new node to the linked list, 
    // retrieving and deleting a specified node in the list
    void addNode(Node* newNode);
    Node* getNode(unsigned position);

private:

    // member data consists of an unsigned integer representing
    // the list size and a pointer to a Node object representing head
    Node* m_listHead;
    unsigned m_listSize;
};

#endif

addNode方法的实现:

//
// Method adds a new node to the linked list
//
void List::addNode(Node* newNode)
{
    Node* theNode = new Node;

    theNode = newNode;
    theNode->next;
    m_listHead = theNode;

    ++m_listSize;
}

【问题讨论】:

  • 列表是双向链接的吗?记忆中的样子是什么?
  • 我认为问题可能出在 addNode 成员函数中。请提供该代码,以便我们确保正确构建列表。
  • 是的,我认为这应该是双向的。我还没有将前一个节点字段添加到元素中。不知道该怎么做。

标签: c++ algorithm data-structures linked-list


【解决方案1】:

试试这个来构建列表:

void List::addNode(int number) 
{ 
    newNode = new Node;
    newNode -> number = number;
    newNode -> next = m_listHead ;
    m_listHead = newNode;
    ++m_listSize; 
} 

它将向头部添加节点。也许您可能希望存储指向尾部的指针并在那里插入节点。

【讨论】:

    【解决方案2】:

    很遗憾,您的代码与您提供的伪代码不同。

    伪代码用于在链表中搜索键,而不是位置。

    伪代码如下:

    Assign head to (node) x.
    while x isn't null and the key inside the current node (x) doesn't match k
      assign x->next to x
    return x
    

    返回值要么是指向包含k的节点的指针,要么是null

    如果您尝试在给定的 位置 找到节点,您的循环将是(注意这是假设您将使用从零开始的索引来访问列表):

    Assign head to (node) x
    assign 0 to (int) pos
    while x isn't null and pos not equal to given position
        assign x->next to x
        increment pos
    return x
    

    结果要么是指向给定位置节点的指针,要么是 null(如果你先到达列表的末尾)

    编辑:如果您正在尝试这样做,您的代码非常接近后者……您能看出区别吗?

    编辑因为我喜欢 OP 提出正确问题的家庭作业 :)

    Node* List::getNodeContaining(int searchValue)
    {
        Node* current = m_listHead;
    
        while (current != 0 && current->number != searchValue)
        {
            current = current->next;
        }
        return current;
    }
    
    Node* List::getNodeAtPos(int position)
    {
         Node* current = m_listHead;
         int pos = 0;
    
         while (current != 0 && pos != position)
         {
            current = current->next;
            pos++;
         }
    
         return current;
    }
    

    【讨论】:

    • 嗯。我理解关键是循环的索引和客户端代码提供的位置的 k。好像有点在我头上……
    • 啊,我明白了。节点的关键字段应该是给定节点中的任何元素? (例如,“int number”表示数字列表)
    • Right :) 如果您的方法应该搜索节点 inside 的内容,则需要将传入的值与每个节点的内容进行比较 (Node-&gt;number)
    • 好吧,看来你正在增加职位。不过,我仍然有些困惑; “当前节点内的键”是指x(当前节点)指向的内容吗?我试图基本上让客户端代码说“给我这个数据位(例如整数4)”并且列表会找到那个元素。我想如果是这样的话,我可能应该将 position 与 current->key... 进行比较
    • 查看我的最新编辑。如果您尝试在列表中搜索 in 的内容,则需要与节点内包含的值进行比较。如果您正在列表中寻找 位置 x 的东西,那么您需要跟踪位置。编辑:(Gah - 现在,把那个编辑弄得一团糟)
    【解决方案3】:

    您的列表与普通列表 ADT 的外观非常不同。与其返回需要客户端了解列表实现的节点,不如返回并接受您正在创建列表的类型。

    在这种情况下,你正在制作一个整数列表,所以你想要

    public:
        void add(int num); //prepends an Item to the list
        int get(int pos);
    

    两者的实现都很简单。 Add 创建一个新节点,并将其链接进去;

    void List::add(int num)
    {
        Node *newNode = new Node;
        newNode->number  = num;
        newNode->next = m_listHead;
        m_listHead = newNode;
        m_listSize++;
    }
    

    那么get也很简单:

    int List::get(int pos)
    {
        if(pos>m_listSize)
            ;//throw an error somehow
        Node *tmp = m_listHead;
        while(pos-->0)
            tmp=tmp->next; 
        return m->number
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-25
      相关资源
      最近更新 更多