C++ 合并两个LinkedList而不创建新的LinkedList

C++ 合并两个LinkedList而不创建新的LinkedList,c++,class,linked-list,c++14,alternating,C++,Class,Linked List,C++14,Alternating,我试图将可执行文件中的两个linkedlist以交替的位置合并到一起。例如,列表1,2,3和列表2 4,5新的列表应为1,4,2,5,3 LinkedList.h文件: class LinkedList { private: struct ListNode { string firstName; string lastName; long int phoneNumber; struct ListNode *next; }; ListNode *head; pub

我试图将可执行文件中的两个linkedlist以交替的位置合并到一起。例如,列表1,2,3和列表2 4,5新的列表应为1,4,2,5,3

LinkedList.h文件:

class LinkedList
{
private:
struct ListNode
{
    string firstName;
    string lastName;
    long int phoneNumber;
    struct ListNode *next;
};
ListNode *head;

public:
LinkedList()
{
    head = nullptr;
}
~LinkedList();
void appendNode(string f, string l, long int p);
void displayList();
};
LinkedList.cpp文件:

LinkedList::~LinkedList()
{
cout << "LinkList destructor" << endl;
}

void LinkedList::appendNode(string f, string l, long int p)
{
    ListNode *newNode;
    ListNode *nodePtr;
    newNode = new ListNode;

    newNode -> firstName = f;
    newNode -> lastName = l;
    newNode -> phoneNumber = p;
    newNode -> next = nullptr;

    if (!head)
        head = newNode;

    else
    {
        nodePtr = head;

        while (nodePtr -> next)
            //while nodePtr is pointing to another node
            nodePtr = nodePtr -> next;
            //move to that node

        nodePtr -> next = newNode;
        //inset the newNode at the end of the linked list
    }
 }

 void LinkedList::displayList()
{
    ListNode *nodePtr;
    nodePtr = head;

    while(nodePtr)
    //while nodePtr is true, meaning there is a node in the list
    {
        cout << nodePtr -> firstName << endl;
        cout << nodePtr -> lastName << endl;
        cout << nodePtr -> phoneNumber << endl;
        nodePtr = nodePtr -> next;
     }
}

我的程序运行良好,包括displayList功能。我只是对如何创建合并函数感到非常困惑。

创建合并函数并不困难。您只需使用一个新的头来记录新列表,然后遍历这两个列表,然后依次将节点从这两个列表移动到新列表,如下所示

 LinkedList LinkedList::merge(LinkedList b)
{
    // if one list is null, return the other
    if (this->head == nullptr)
        return b;
    if (b.head == nullptr)
        return *this;

    LinkedList newlist;
    ListNode *ap = this->head, *bp = b.head, *p = nullptr;
    // if two pointer is all not null, move node from these to new list in turn
    while (ap != nullptr && bp != nullptr)
    {
        if (newlist.head == nullptr)
        {
            p = newlist.head = ap;
            ap = ap->next;
            p = p->next = bp;
            bp = bp->next;
        }
        else
        {
            p = p->next = ap;
            ap = ap->next;
            p = p->next = bp;
            bp = bp->next;
        }
    }
    // maybe one list is longer, and there is some node left.
    if (ap != nullptr)
        p->next = ap;
    if (bp != nullptr)
        p->next = bp;
    //clear original list
    this->head = b.head = nullptr;
    //if you want to merge list b to the caller list, you can change to
    //this->head = newlist->head and beginning part also need some modification.
    return newlist;
}

也许您不想更改原始列表,那么您可以复制该值并为新列表创建新节点。

合并是将已从源列表复制或将从源列表窃取的节点插入到目标列表的特定位置

我假设您希望在该操作中将源列表视为不可变的,因此将复制源节点

对复制和插入操作都有用的是一个-something,它指向一个节点,并且在
++
-op之后指向列表中的下一个节点或列表末尾后面(相当于
nullptr
):

(我在单个源文件中编写这样的代码片段;将实现移动到.cpp文件或内联它们)

并递增
it_one
直到它指向要插入副本的目标列表的元素,递增
it_two
直到它指向要复制的源列表的节点,然后

ListNode& one = *it_one;
ListNode* ptwo = new ListNode(*it_two); // copies

ptwo->next = one.next;
one.next = ptwo;
本质上就是这样

因此,这里真正的问题不是技术上如何合并,而是操作的复杂性

只要两个列表都按照要创建的结果列表的预定顺序排序,您就可以重复使用迭代器,从而使用
N=max(size(listOne)、size(listwo))
简单地遍历两个列表及其
O(N)

如果您必须对它们进行初步排序以保持合并本身的廉价性,那么这种排序会导致
O(N log N)
复杂性


作为补充说明,存储迭代器也简化了其他操作的实现;e、 g.展示它们只是简单的

for (const auto& node : ListOne) {
    std::cout << node.firstName << std::endl;
    std::cout << node.lastName << std::endl;
    std::cout << node.phoneNumber << std::endl;
}
for(const auto&node:ListOne){

std::你可以简单地在
LinkedList
中添加一个方法,该方法接受
LinkedList
并迭代传入的参数,并为传入的
LinkedList
@Gread.and.power.Oz中的每个节点调用
appendNode
。哦,我明白你在说什么了。我会给它一个提示,请用传入的代码编辑你的帖子问题,以便我能更简洁、正确地回答您的问题。@Gread.and.power.Oz您认为您可以为该方法更正一些伪代码吗?因为我在您的
上画了几个空格,而在您的
appendNode
方法的
循环中画了几个空格。首先,方法签名:
合并(LinkedList&b)
then
ListNode*node=b.head;while(node){appendNode(node);node=node->next;}
注意复制
节点
,否则会将两个列表相互链接。
auto it_one = listOne.begin();
auto it_two = listTwo.cbegin();
ListNode& one = *it_one;
ListNode* ptwo = new ListNode(*it_two); // copies

ptwo->next = one.next;
one.next = ptwo;
for (const auto& node : ListOne) {
    std::cout << node.firstName << std::endl;
    std::cout << node.lastName << std::endl;
    std::cout << node.phoneNumber << std::endl;
}