'Recursive way to delete the last element of a singly linked list?

int main(){
    IntSLList list1,list2;

    list1.addToHead(1);
    list1.addToHead(2);
    list1.addToHead(3);
    list1.printAll();

    IntSLLNode *p;
    list1.assignvalues(p);

    //p....p->next...p->next->next
    //p refers to the first node of the linked list


    return 0;
}

IntSLList* IntSLList::deletelast(IntSLLNode *p)
{

    if(p==NULL || p->next ==NULL)//check this one as my base case
    {
        return NULL;
    }
    else
    {
        p->next = deletelast(p->next);
    }

}
void IntSLList::assignvalues(IntSLLNode *p)
{
    p=head;
}

Does anybody have any idea what I am doing wrong here? it says that p->next has the wrong data type to be assigned as it is...



Solution 1:[1]

Try this:

int main() {
    IntSLList list1;

    list1.addToHead(1);
    list1.addToHead(2);
    list1.addToHead(3);

    list1.deletelast(list1->head);
    list1.printAll();
}

void IntSLList::deletelast(IntSLLNode *p){
    if (p->next->next == NULL) {
        p->next = NULL;
        return;
    }
    deleteLast(p->next);
}

Some corrections:

  1. You can access the list's head directly with list1->head
  2. The return type of deleteLast should be just void
  3. The base case should be two nodes before NULL. Remember this is a singly list, if you stop at one node before NULL, how can you set the pointer of the previous node to not pointing to the current node? This list has only one direction, once you move forward, you can't go back
  4. You do not actually need a recursion. It has the same time complexity as using loop. Both are O(n) time complexity

Solution 2:[2]

Assuming you want to return the abandoned item (the one that is de-listed from the list) from deletelast.

Try this:

IntSLLNode *IntSLList::deletelast(IntSLLNode *p)
{
    IntSLLNode *pNextNext = p->next->next;

    if(pNextNext == NULL)
    {
        // Next element is the last element, because
        // the element after that does not exist (pNextNext)
        p->next = NULL; // make this element the last element
        return pNextNext; // we are returning the abandoned element
                          // so caller can make memory de-allocations
                          // or whatever with the abandoned last element
    }
    else
    {
        p->next = deletelast(p->next);
    }

}

And you can call the recursive function like this:

IntSLList *pList;
// populate pList
IntSLLNode *abandonedNode = IntSLList::deletelast(pList->head);
// now you can do whatever you want with abandonedNode. Also, the
// variable pList still points to the list, now reduced by one element.

Solution 3:[3]

Solution: to delete last node of linklist using recursive function.

    struct node* deletenodeback(struct node*list)
    {
        if(list==NULL || list->next==NULL) {
           return NULL;
        }
        else {
           list->next=deletenodeback(list->next);
           return list;
        }
    }
    
    main(){
        struct node *h=NULL;
        h=insert(h,2); //insert remaining nodes
        h=deletenodeback(h);
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3