最后插入C ++

时间:2018-08-18 12:56:36

标签: c++ list

我写了一些代码,可以创建一个链表,将元素插入到开头或结尾,然后显示它。

struct ListElem
{
    int        info;
    ListElem * next;
};

// shortcut for list = pointer to a list element
typedef ListElem * List;

// empty list is a Null Pointer
const List emptyList = 0;

void printList(List lst) {
        for (; lst!= 0; lst = lst->next) {
            cout << lst->info << endl;
        }
}
void insertElem(List& lst, int info) {
    ListElem *ptrElem = new ListElem;
    ptrElem->info = info;
    ptrElem->next = lst;
    lst = ptrElem;
}
void insertLast(List& lst, int info) {
    ListElem *ptrElem = new ListElem;
    ptrElem->info = info;
    ptrElem->next = NULL;
    if (lst == emptyList) {
        insertElem(lst, info);
        return;
    }
    else {
        while (lst ->next) {
            lst = lst->next;
        }
        lst->next = ptrElem;
    }
}

我尝试了main上的insertLast函数:

int main()
{
    // fill List with values 1 to 10
    List list1 = emptyList;
    for (int value = 1; value <= 10; value++)
    {
        //insertElem( list1, value ); 
        insertLast(list1, value);
    }

    //print list
    printList(list1);  // should provide sequence 1 2 3 ... 10 

但是出于某种原因,printList仅显示9和10,而不是1,2,3,..,10。仅在insertLast中会发生此问题。 insertElem似乎工作正常。

5 个答案:

答案 0 :(得分:1)

问题在于,在insertLast()内部,您通过引用传递了列表参数。也就是说,对列表所做的每个更改都将在函数外部可见。在这些行上-while (lst ->next) {lst = lst->next;},您将更改列表引用,因此列表的第一个节点会随着每次添加而被修改。

解决方案是采用一个辅助迭代器节点,以迭代您的列表,或按值传递您的List,像现在一样更改列表,然后返回修改后的副本。

下面是insertLast()方法,该方法经过重写以使用辅助节点迭代列表:

void insertLast(List& lst, int info) {
    ListElem *ptrElem = new ListElem;
    ListElem *aux = lst;

    ptrElem->info = info;
    ptrElem->next = NULL;
    if (lst == emptyList) {
        insertElem(lst, info);
        return;
    }
    else {
        while (aux ->next) {
            aux = aux->next;
        }
        aux->next = ptrElem;
    }
}

答案 1 :(得分:0)

此行为的原因是,在您的函数调用最后插入元素的函数之后,发生的事情是您的链表标头开始指向链表的倒数第二个元素,而不是链表的第一个元素。

在您的函数中,此方法的解决方法很简单:最后插入元素,只需将一个临时变量设置为等于链表标题,然后使用此临时变量遍历链表,而无需修改您要的链表标题作为函数参数传递。

答案 2 :(得分:0)

这是因为您使用的引用非常糟糕 查看您的insertLast函数

void insertLast(List& lst, int info) {
    ListElem *ptrElem = new ListElem;
    ptrElem->info = info;
    ptrElem->next = NULL;
    if (lst == emptyList) {
        insertElem(lst, info);
        return;
    }
    else {
        while (lst ->next) {
            lst = lst->next;
        }
        lst->next = ptrElem;
    }

您将lst设置为最后一项,而lst是引用,因此在您的主要功能list1中已更改,您失去了列表 尝试:

void insertLast(List& lst, int info) {
    ListElem *ptrElem = new ListElem;
    List* newlst = lst;
    ptrElem->info = info;
    ptrElem->next = NULL;
    if (lst == emptyList) {
        insertElem(lst, info);
        return;
    }
    else {
        while (newlst ->next) {
            newlst = newlst->next;
        }
        newlst->next = ptrElem;
    }

答案 3 :(得分:0)

两个问题:

  • insertLast函数的开头,您总是创建一个新元素,关于yu仅当它不是列表中的第一个元素时才使用它。在这种情况下,您总是会发生内存泄漏。

  • 使代码运行异常的第二个问题是,您将列表的标题更改为指向每个插入中最后一个位置之前的位置。要避免这种情况,您可以使用ListElem指针,该指针将指向列表的开头,对此指针所做的更改将对原始列表的开头指针没有影响。

此功能将为您完成工作:

void insertLast(List& lst, int info) {
    if (lst == emptyList) {
        insertElem(lst, info);
        return;
    }
    else {
        ListElem *ptrElem = new ListElem;
        ptrElem->info = info;
        ptrElem->next = NULL;
        ListElem* temp = lst;
        while (temp->next) {
            temp = temp->next;
        }
        temp->next = ptrElem;
    }
}

答案 4 :(得分:0)

您的方法insertLast修改输入lst,因此它指向main中for循环末尾的最后一个元素。这就是printList仅给您最后两个数字的原因。

可以在一个功能中完成。如果您想在前面添加元素,则需要另一个,但这不是您的问题。

void insertElem(List& lst, int info) {
    List elemntToInsert = new ListElem();
    elemntToInsert->info = info;
    elemntToInsert->next = nullptr;

    //Check if input is null list
    if (lst == nullptr)
    {
        lst = elemntToInsert;
    }
    else //Else append at the end
    {
        List lastElement = lst;
        while (lastElement->next != nullptr)
            lastElement = lastElement->next;
        lastElement->next = elemntToInsert;
    }
}