需要一些关于 C++ 中的类的建议,双向链表

Posted

技术标签:

【中文标题】需要一些关于 C++ 中的类的建议,双向链表【英文标题】:Need some advice with classes in C++, doubly linked list 【发布时间】:2016-06-27 02:33:14 【问题描述】:

我正在尝试打印列表中的所有元素,但输出错误。

代码得到 2、0 和 10,当我调用过程“travel_in”时,它只显示 0、2。

对我的 del_start() 有一些疑问,它删除了 0 而不是 2..

我做错了什么?

使用 Cygwin 在 Windows 64 位中编译

输出

2 0 10 0 2

这里是代码

# include < iostream >

# include < stdio.h >
using namespace std;

template <class clali>
class double_list

    protected:
        clali node1;
    clali *listad;
public:
    double_list()//constructor
    
        listad=NULL;
    
    void insert_strt(clali node1)
    
        clali *temp;
        temp=new clali;
        *temp=node1;
        
        //check if list is not empty
        if (listad==NULL)
        
            listad=temp;
            listad->next=NULL;
            listad->before=NULL;
        
        else
        
            temp->next=listad;
            listad->before=temp;
            temp->before=NULL;
            listad=temp;    
        
    

    int vertam()
    
        int res=0;
    clali *temp;
    temp=listad;
    if (temp==NULL)
    
        cout<<"Empty list!"<<endl;
        res=0;
    
    else
        while(temp!=NULL)
        
            res++;
            temp=temp->next;
        
    return res;
    
    

    void insert_mid(clali node1, int pos)
    
        int i;
        clali *temp,*temp2;
        temp2=new clali;
        temp=listad;
        if(pos<vertam)
    
        for(i=1;i<pos;i++)
        temp=temp->next;
        *temp2=node1;
        temp2->next=temp->next;
        temp->before=listad;
        temp->next=temp2;
        
    
    else
    cout<<"Cant show the data!"<<endl;
    
    
    clali del_start()
    
        clali a,*temp;
        a=*listad;
        temp=listad;
        listad=listad->next;
        delete temp;
        return a;
    
    
    void insert_end(clali node1)
    
        clali *temp,*temp2;
        temp=listad;
    while(temp->next!=NULL)
    
        temp=temp->next;
    
    temp2=new clali;
    *temp2=node1;
    temp->next=temp2;
    temp2->before=temp;
    temp2->next=NULL;
        
    
    clali  clear_end()
    
        clali b,*temp,*temp2;
        int j=1;
        temp=listad;
        do
        
            temp=temp->next;
            cout<<"Element : "<<j<<endl;
            j++;
        while(temp->next!=NULL);
        b=*temp;
        temp2=temp->before;
        temp2->next=NULL;
       // delete temp;
        return b;
    
    void travel_in()
    
        clali *temp;
        temp=listad;
        while(temp->next!=NULL)
        
        cout<<temp->data<<endl;
        temp=temp->next;
        
    

    
;

struct integer

int data;
integer*next,*before;
;
typedef struct integer Integer;
int main()

    Integer node;
    node.next=NULL;
    node.before=NULL;
    double_list<Integer>  test_list;
    
    test_list.insert_strt(node);
    node.data=2;
    cout<<node.data<<endl;
    test_list.insert_end(node);
    node.data=0;
    cout<<node.data<<endl;
    test_list.insert_end(node);
    node.data=10;
    cout<<node.data<<endl;
test_list.del_start();
    test_list.travel_in();
    

【问题讨论】:

【参考方案1】:

我看到至少一个明显的错误。初步分析表明listad 类成员是指向双向链表中第一个元素的指针。在这种情况下,以下内容显然是错误的(为了便于阅读,请重新格式化,请正确缩进您的代码):

void insert_mid(clali node1, int pos)

    int i;
    clali *temp,*temp2;
    temp2=new clali;

这个类方法的目的显然是将新节点插入到链表的中间。

temp2 是新节点。

    temp=listad;

    if(pos<vertam)
    
        for(i=1;i<pos;i++)
            temp=temp->next;

temp 似乎是列表中间的插入位置。

        temp->before=listad;

由于某些不清楚的原因,此代码尝试将列表中间现有节点的before 指针设置为列表的头部。这是没有意义的,而且是错误的。

【讨论】:

但我不明白,好吧,我明白你的意思,但为什么它会打印 2 0 10 2?这是我的疑问..【参考方案2】:

让我们在main()中一步一步来。

当您第一次调用insert_strt() 时,参数node 具有成员data 的垃圾值。因此,在test_list 的开头插入了一个带有一些垃圾值dataInteger 对象。然后在列表末尾插入Integer 对象,分别为data 2 和0。

稍后,您从test_list 中删除第一个clali 对象,这将删除其data 字段中具有垃圾值的对象。因此,删除后,您的对象的 data 值为 2,列表中的值为 0。

最后,您使用travel_in() 打印列表,但它并没有按照您的想法执行。它实际上在做的是,如果列表至少有一个元素,那么它会打印列表中除最后一个元素之外的所有元素。如果列表为空,则会导致分段错误(在while 循环的情况下,temp 将是NULL)。所以它会打印:2(但你的列表有 2 和 0)。

你可以写travel_in()如下。

void travel_in()

  clali *temp = listad;
  while(temp != NULL)
  
    cout << temp->data << " ";
    temp = temp->next;
  
  cout << endl;

顺便说一下,注释/删除main() 函数中的cout 语句。他们可能会让你感到困惑。

【讨论】:

以上是关于需要一些关于 C++ 中的类的建议,双向链表的主要内容,如果未能解决你的问题,请参考以下文章

双向链表的基础操作(C++实现)

c++实现双向链表的常用功能

c++中的双向链表写法,主要实现(增删查改,链表逆置,构造函数,运算符重载,等)

数据结构——双向链表

C++双向链表

双向链表模板向量中的输入排序(C++)