从双链接列表中删除偶数节点c ++

时间:2016-06-09 09:06:35

标签: c++

我尝试通过递归删除甚至在双向链表中的节点。问题是它删除了节点但仍然在已删除的节点空间中显示垃圾。

这是输出:

这是原始列​​表:2 - > 2 - > 23 - > 2 - > 78 - > 5 - > 2

此列表包含7个项目

偶数的数量是:5

删除的偶数节点数为:5

结果列表是...... 23 - > 5

***************删除偶数后,我得到了回复,你有同样的问题吗?************** ********

现在倒退:5 - > 27303024 - > 27302960 - > 23 - > 27302928 - >的 0

此列表包含2个项目

所有数据的总和是:28

int removeEven(node*& head) {
    // double pointer to use the address of pointer head
    node ** deleteNode = &head;
    //if is the end of the list stop
    if(head==NULL)
        return 0;
    //if is even
    if((*deleteNode) -> data %2==0)
    {
        node * helper = *deleteNode;
        *deleteNode = helper -> next;
        delete helper;

        return 1+ removeEven(helper -> next);
    }   
    //but if is an odd number
    else if ((*deleteNode) -> data %2)
    {
        //traverse to the next node
        deleteNode = &(*deleteNode)->next;
        //calls itself so that we can start againg to check in the new node.
        return removeEven(head -> next);
    }
}

有人告诉我,改变这样的功能会有所帮助但是我得到了很多错误请帮助

//Remove even numbers
node* recfunremoveEven(node *head,node *prevnode, int* count) //helper function for remove even nodes
{
    if(head==NULL)
        return NULL;
    if(head->data %2 == 0) //data is even
    {
        *count+=1;
        free(head);
        node* next = recfunremoveEven(head->next,head,&count); //recursive call
        if(prevnode)
        {
            prevnode->next = next;
            next->previous = prevnode;
        }
        return next;
    }
    return recfunremoveEven(head->next,&count);
}

int removeEven(node*& head)
{
    int count=0;
    recfunremoveEven(head,&count);
    return count;
}

编译时出现以下错误:

  

g ++ -g -std = c ++ 11 -o proftest dlist.h dlist.cpp main.cpp supplied.o

     

dlist.cpp:在函数'node * recfunremoveEven(node *,node *,int *)'中:

     

dlist.cpp:30:53:错误:无法将'int **'转换为'int *'作为参数   '3'到'node * recfunremoveEven(node *,node *,int *)'node * next =   recfunremoveEven(头戴式>接着,头,&安培;计数); //递归调用^

     

dlist.cpp:38:42:错误:无法将'int **'转换为'node *'作为参数   '2'到'node * recfunremoveEven(node *,node *,int *)'返回   recfunremoveEven(头戴式>接着,&安培;计数); ^

     

dlist.cpp:在函数'int removeEven(node *&)'中:dlist.cpp:45:29:   错误:无法将'int *'转换为'node *'以将参数'2'转换为'node *   recfunremoveEven(node *,node *,int *)'recfunremoveEven(head,& count);

这是.h文件,以防有人需要看到它

//doubly linked list
#include <iostream>
#include <cstring>
#include <cctype>
#include <cstdlib>


struct node
{
    int data;
    node * previous;
    node * next;
};

/* These functions are already written and can be called to test out your code */
void build(node * & head);  //supplied
void display(node * head);  //supplied
void destroy(node * &head); //supplied
//Recursively compute and return the number of nodes that contain even number
//in the doubly linked list
int countEven(node *head);
//Recursively remove all the nodes that contain even number in the doubly linked list
//and return the number of nodes removed 
int removeEven(node*& head);

1 个答案:

答案 0 :(得分:0)

free(head)之后,您不能取消引用head,但是您可以。{/ p>

你还添加了一些&你不应该的地方(在递归时)并且在几个函数调用中省略了一个参数。

但我认为你通过绕过“前一个”节点过度复杂化了。

有三种情况需要处理:

  1. 列表为空,
  2. 第一个节点是奇数,
  3. 第一个节点是偶数。
  4. 第一种情况是微不足道的 第二个和第三个非常相似:

    • 从列表的其余部分递归删除偶数节点。
    • 调整删除结果的previous指针。
    • 如果head是偶数,请将其删除并增加计数。
    • 返回head(如果它很奇怪)或递归结果(如果head是偶数)。

    我认为应该这样做(小心 - 未经测试):

    node* removeEvenWorker(node* head, int* count)
    {
        // Case 1
        if (head == nullptr)
        {
            *count = 0;
            return head;
        }
    
        // Recurse
        node* rest = removeEvenWorker(head->next, count);
    
        // Cases 2 & 3: Set up the first node.
        if (head->data % 2 != 0)
        {
            // Keep 'head'; link the recursive result to it.
            if (rest != nullptr)
            {
                rest->previous = head;
            }
            head->next = rest;
            return head;
        }
        else
        {
            // Discard 'head'
            if (rest != nullptr)
            {
                rest->previous = nullptr;
            }
            free(head);
            *count += 1;
            return rest;
        }
    
    }
    

    并称之为:

    int removeEven(node*& head)
    {
        int count = 0;
        head = removeEvenWorker(head, &count);
        return count;
    }