C ++双链表打印

时间:2016-01-05 01:00:55

标签: c++ doubly-linked-list

我对双向列表类有一些困难,这是我大学项目的一部分。班级代码是这样的:

class container
{
public:
    class node
    {
        public:
        node * prev;
        node * next;
        int value;
    };

container(int v);

node *start; // first element of the list
node *finish; // last element of the list
void insert_start(node *start, int val);
void print_container(); 
}

函数insert_start应该将元素添加到列表的开头。代码如下:

void container :: insert_start(node *start, int val)
{
    if(start!=NULL)
    {
        cout << "in insert_start" << endl;
        cout << "number added:" << val << endl;

        node *element = new node;

        element->value=val;
        element->next=start;
        start=element;
        start->prev=NULL;
    }
    else
    {
        cout << "List is empty" << endl;
    }
}

函数print_container应该打印我的链表。代码如下所示:

void container::print_container()
{
    node *tmp;
    tmp = start;
    while(tmp!=nullptr)
    {
        cout << tmp->value << endl;
        tmp=tmp->next;
    }
}

不幸的是,我的程序存在两个问题。首先,它 似乎在添加的数据结构元素中添加了相同的随机值。其次,在执行函数print_container期间存在分段错误。我想它可能是insert_start函数中的一个bug(或错误),但我对此并不完全确定。

这是测试程序:

int main(void)
{
    int how_many_pieces;

    container L(6);

    L.insert_finish(L.finish,3);
    cout << "added element: " << L.finish->value << endl;

    L.insert_start(L.start,8);
    cout << "added element: " << L.start->value << endl;

    L.insert_start(L.start,12);
    cout << "added element: " << L.start->value << endl;


   //show elements of the L list
   L.print_container();
   cout << "\n";

return 0;
}

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

在此代码中:

void container :: insert_start(node *start, int val)
{
    if(start!=NULL)

start是最后一行应该引用的?是检查参数值还是公共类值?

此外,如果列表为空,您可能希望执行除打印消息之外的其他操作。该列表必须以某种方式开始

(齿顶)

至少有两种方法可以防止出现此问题。我会一次展示三个:

void container :: insert_start(node *node_to_insert, int val)
{
    if (this->start != NULL)  // is list not empty?

它看起来几乎一样,对吧?

  • 形式参数名称现在表示其含义。该名称表明指向的节点将被添加到列表中。
  • 通过this关键字访问对象实例值。这在语法上消除了同名变量的范围,并且真正帮助程序员轻松发现了什么。
  • 该评论阐明了该声明的高级意图,使任何检查代码的人都可以轻松识别可能存在的差异。
  • 参数名称不再与对象成员名称匹配。虽然让名称相互平行通常很有用(p_x, p_y, p_z用于三个参数值来初始化成员变量x, y, z),但为了简单和清晰起见,它们确实应该保持不同。

答案 1 :(得分:1)

首先,不要将节点作为参数传递 - 您不需要。容器类已经可以看到开始和结束节点,并且传递它们只会让事情混乱。

其次,你应该将这些设为私有,以便任何使用该类的人都必须使用你的insert_start或insert_finish函数。

新课程将如下所示:

class container
{
    private:
        class node
        {
            public:
            node * prev;
            node * next;
            int value;
        };

        node *start; // first element of the list
        node *finish; // last element of the list

    public:
        container(int v);

        void insert_start(int val);
        void print_container();
};

第三,确保为每个方向设置链接。例如,在insert_start函数中:

node *element = new node;

element->value = val;
element->next = start;
element->prev = NULL;
start->prev = element; //This part was missing
start = element;

如果不将原始节点重新引用到新节点,则会将其视为正常的单链接列表。如果您想要双向链表提供的遍历灵活性,则需要正确设置链接。