Segregate even and odd nodes in a Linked List in C++

半世苍凉 提交于 2021-01-28 19:28:42

问题


So, I am self teaching Data Structure and Algorithm. While solving some problems I came across following problem where I have to segregate odd and even nodes of linked list.

http://www.geeksforgeeks.org/segregate-even-and-odd-elements-in-a-linked-list/

Following is the problem statement:

Given a Linked List of integers, write a function to modify the linked list such that all even numbers appear before all the odd numbers in the modified linked list. Also, keep the order of even and odd numbers same.

I know this question is asked so many times. But I am still not able to find the answer. I know there are multiple ways to solve this problem but trying to solve this in following way

    1. Traversing over the original list and moving all the odd elements to new oddlist. 
       Same time delete those elements from the original list.
    2. Now original list should have even elements and oddlist will have odd elements.
    3. concatenate original list and oddlist 

Which looks straight forward and I thought just by removing node and adjusting few pointer would solve the problem but it is not the case

#include <iostream>
#include <stdlib.h>

using namespace std;

struct Node {
    int data;
    struct Node *next;
};


struct Node *Insert_at_bottom(struct Node* head, int data) {
    struct Node *node;

    node = new struct Node;
    node->data = data;
    node->next = NULL;
    //node->prev = NULL;

    struct Node *temp;

    if (head == NULL) {
        head = node;
        return head;
    }

    temp = head;
    while(temp->next != NULL){
        temp = temp->next;
    }

    temp->next = node;
    //node->prev = temp;
    return head;
}




struct Node *seperate_elements(struct Node *head) {
    struct Node *temp = head;
    struct Node *oddhead = NULL;
    struct Node *temp1 = NULL;
    while (temp != NULL) {
        if (temp->data%2 == 0) {
            cout << "even:" << temp->data << "\n";


        }
        else{
            cout << "odd:" << temp->data << "\n";
            oddhead = Insert_at_bottom(oddhead, temp->data);

            // I am messing something here. Not sure what!!!
            temp1 = temp->next;
            temp->next = temp1->next;
            //temp->next = temp->next->next;
            free(temp1);
        }

        temp = temp->next;
    }
    return oddhead;
}

struct Node *concate_list(struct Node *head, struct Node *oddhead) {
    struct Node *temp = head;
    while(head->next!=NULL)
    {
        head = head->next;
    }
    head->next = oddhead;
    return temp;

}

void print_list(struct Node *head){
    while(head){
        cout << head->data << " ";
        head = head->next;
    }
}

int main(){

    struct Node *head = NULL;
    struct Node *head2 = NULL;
    struct Node *finalhead = NULL;
    head = Insert_at_bottom(head, 1);
    head = Insert_at_bottom(head, 2);
    head = Insert_at_bottom(head, 8);
    head = Insert_at_bottom(head, 4);
    head = Insert_at_bottom(head, 5);
    head = Insert_at_bottom(head, 7);

    head2 = seperate_elements(head);


    finalhead = concate_list(head, head2);
    //cout << "\n";
    print_list(finalhead);

    return 0;
}

so when I execute above code I am getting

1 8 4 5 1 5 instead of 2 8 4 1 5 7

Now, I think I am missing something while deleting the node. Not sure what I am doing wrong here. I think I am not taking proper care of pointer adjustment. I would really appreciate any help here.

Thanks,


回答1:


If you don't want to create a second list, which is not really necessary, the best thing you can do is an algorithm like this:

1) find the last element of the list (you can do that in linear time)

2) start traversing the list, each time you find an odd element, you put it at the end of the list. It is easy, you just need to adjust the pointers of the preceding element, the following element, the odd element itself and of the last element.

Do #2 till you don't find the last element of the list. To keep track of this you will have to save two pointers for the last element, one that you will update as you put odd elements in the last and the other that will just mark you the ending of the original list, allowing you to terminate the algorithm.



来源:https://stackoverflow.com/questions/41070533/segregate-even-and-odd-nodes-in-a-linked-list-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!