C++ 在C+中隔离链接列表中的偶数和奇数节点+;

C++ 在C+中隔离链接列表中的偶数和奇数节点+;,c++,algorithm,linked-list,C++,Algorithm,Linked List,所以,我自学数据结构和算法。在解决一些问题时,我遇到了以下问题:我必须分离链表的奇偶节点 以下是问题陈述: 给定一个整数链表,编写一个函数修改链表,使修改后的链表中所有偶数出现在所有奇数之前。同时,保持偶数和奇数的顺序相同 我知道这个问题被问了很多次。但我仍然无法找到答案。我知道有很多方法可以解决这个问题,但我试着用下面的方法来解决这个问题 1. Traversing over the original list and moving all the odd elements to n

所以,我自学数据结构和算法。在解决一些问题时,我遇到了以下问题:我必须分离链表的奇偶节点

以下是问题陈述:

给定一个整数链表,编写一个函数修改链表,使修改后的链表中所有偶数出现在所有奇数之前。同时,保持偶数和奇数的顺序相同

我知道这个问题被问了很多次。但我仍然无法找到答案。我知道有很多方法可以解决这个问题,但我试着用下面的方法来解决这个问题

    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 
直截了当地向前看 我认为仅仅通过移除节点和调整少量指针就能解决问题,但事实并非如此

#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;
}
现在,我想我在删除节点时遗漏了一些内容。我不知道我做错了什么。我认为我没有适当注意指针的调整。我真的很感激这里的任何帮助


谢谢,

如果您不想创建第二个列表(这并不是必需的),那么最好使用如下算法:

1) 找到列表的最后一个元素(可以在线性时间内完成)

2) 开始遍历列表,每次找到奇数元素时,都将其放在列表的末尾。这很简单,您只需要调整前一个元素、后一个元素、奇数元素本身和最后一个元素的指针


执行2,直到找不到列表中的最后一个元素。要跟踪这一点,您必须为最后一个元素保存两个指针,一个在最后一个元素中放入奇数元素时更新,另一个只标记原始列表的结尾,允许您终止算法。

删除第一个节点时,您不会在
main
中更新
head
。它总是指向节点1。如果你想挑战的话,还有一个稍微复杂一点的算法可以让你在适当的位置完成。查看链接列表,在头部前保留一个额外的节点(没有有效负载),也可以获得更简单的编码(还有)。最后一个链接是关于在尾部增加列表;就像Lisp的一样。
1 8 4 5 1 5 instead of 2 8 4 1 5 7