在C++中实现双向链表。

huangapple go评论55阅读模式
英文:

implementing doubly linked list in C++

问题

我在实现双向链表时遇到了问题,特别是在交换相邻元素的函数中。

这是我的原始代码:

#include <iostream>
using namespace std;

struct node {
    int data; 
    node *prev;
    node *next;
};
node *head = NULL;

node* getNewNode (int i){
    node *newNode = new node; //在堆上分配动态内存
    newNode->data = i;
    newNode->prev = NULL;
    newNode->next = NULL;
    return newNode;
}

void InsertAtHead(int i){
    node *newNode = getNewNode(i);
    if (head == NULL){   //处理在列表中插入第一个节点的情况。
        head =  newNode;
        return;
    }
    
    newNode->next = head;
    head->prev = newNode;
    head = newNode;    
}

void swapAdjacent() {
    node *temp = head;
    while (temp != NULL ) {
        node *temp1 = temp;
        node *temp2 = temp->next;
        temp1->next = temp2->next;
        temp2->prev = temp1->prev;
        if (temp1->prev != NULL) {
            temp1->prev->next = temp2;
        }
        temp1->prev = temp2;
        temp2->next = temp1;
       
        if (temp == head) {
            head = temp2;
        }
        temp = temp->next->next;
    }
}

void display (){
    node *temp = head;
    while (temp != NULL){
        cout  <<temp->data << '\t';
        temp = temp->next;    
    }
    cout << '\n';
}

int main (){
    InsertAtHead(8); 
    InsertAtHead(4);
    InsertAtHead(12);
    InsertAtHead(3);
    InsertAtHead(-8);
    InsertAtHead(7);
    cout << "原始列表为:" << endl;
    display();
    swapAdjacent();
    cout << "交换相邻元素后的列表为:" << endl;
    display();
       
    return 0;
}

原始列表为:

7       -8      3       12      4       8

调用swapAdjacent()后得到的输出是:

-8      7       3       4       12      8

而我期望的输出是:

-8     7       12      3        8       4

我尝试用纸和笔可视化它,做了几次尝试,甚至使用了ChatGPT,但都没有成功。无论如何,我都无法获得我想要的输出。

我的问题是,我希望swapAdjacent()函数能够产生我期望的输出,而不是它当前产生的输出。

英文:

I have trouble implementing a doubly linked list, especially in a function that swaps adjacent elements.

Here is my original code:

#include &lt;iostream&gt;
using namespace std;
struct node {
int data; 
node *prev;
node *next;
};
node *head = NULL;
node* getNewNode (int i){
node *newNode = new node; //allocate a dynamic memory in the heap
newNode-&gt;data = i;
newNode-&gt;prev = NULL;
newNode-&gt;next = NULL;
return newNode;
}
void InsertAtHead(int i){
node *newNode = getNewNode(i);
if (head == NULL){   //addressing inserting the first node in the list.
head =  newNode;
return;
}
newNode-&gt;next = head;
head-&gt;prev = newNode;
head = newNode;    
}
void swapAdjacent() {
node *temp = head;
while (temp != NULL ) {
node *temp1 = temp;
node *temp2 = temp-&gt;next;
temp1-&gt;next = temp2-&gt;next;
temp2-&gt;prev = temp1-&gt;prev;
if (temp1-&gt;prev != NULL) {
temp1-&gt;prev-&gt;next = temp2;
}
temp1-&gt;prev = temp2;
temp2-&gt;next = temp1;
if (temp == head) {
head = temp2;
}
temp = temp-&gt;next-&gt;next;
}
}
void display (){
node *temp = head;
while (temp != NULL){
cout  &lt;&lt;temp-&gt;data &lt;&lt; &#39;\t&#39;;
temp = temp-&gt;next;    
}
cout &lt;&lt; &#39;\n&#39;;
}
int main (){
InsertAtHead(8); 
InsertAtHead(4);
InsertAtHead(12);
InsertAtHead(3);
InsertAtHead(-8);
InsertAtHead(7);
cout &lt;&lt; &quot;The original list is: &quot; &lt;&lt; endl;
display();
swapAdjacent();
cout &lt;&lt; &quot;The list after swapping the adjacent elements is: &quot; &lt;&lt; endl;
display();
return 0;
}

The original list is:

7       -8      3       12      4       8

The output I got after calling swapAdjacent() is:

-8      7       3       4       12      8

While I am looking for:

-8     7       12      3        8       4

I tried visualizing this with pen and paper, did several attempts to look it up, and I even used ChatGPT, but to no avail. I always don't get the output I am looking for.

My question is that I want the swapAdjacent() function to produce the desired output and not the output it is currently producing.

答案1

得分: 1

以下是翻译好的部分:

  • temp = temp-&gt;next-&gt;next; 多走了一步(正如你在输出中也可以注意到):因为 temp 现在指向了一个与其原始后继节点进行了交换的节点,它现在指向了下一对节点的直接前驱节点。所以你只需要前进一步:temp = temp-&gt;next;

  • 你的代码最多对 prevnext 指针进行了 5 次赋值。这应该引起你的警觉。当交换两个相邻的节点时,最多会影响 4 个节点:这两个节点本身,对这一对节点的后继节点和前驱节点。当这 4 个节点被正确排序后,会有 3 个双向连接受到影响,因此可能需要更新多达 6 个指针。你遗漏了一个更新,就是前驱节点的 next 指针的更新。

  • 你的代码在访问 temp2-&gt;next 时没有确保 temp2 不为空。当你的链表节点数为奇数时可能会发生这种情况。我建议更改你的 while 条件,以确保存在一个节点

以下是已更正的代码:

void swapAdjacent() {
    node *temp = head;
    while (temp &amp;&amp; temp-&gt;next) { // 要求存在一对节点
        node *temp1 = temp;
        node *temp2 = temp-&gt;next;
        temp1-&gt;next = temp2-&gt;next;
        if (temp1-&gt;next) { // 必须也在相反的方向上进行更改
            temp1-&gt;next-&gt;prev = temp1;
        }
        temp2-&gt;prev = temp1-&gt;prev;
        if (temp1-&gt;prev) {
            temp1-&gt;prev-&gt;next = temp2;
        }
        temp1-&gt;prev = temp2;
        temp2-&gt;next = temp1;
       
        if (temp == head) {
            head = temp2;
        }
        temp = temp-&gt;next; // 只需要单步前进
    }
}

希望这对你有所帮助。

英文:

There are these issues:

  • temp = temp-&gt;next-&gt;next; is making one step forward too many (as you can also notice in the output you get): as temp now points to a node that was swapped with its original successor, it is now pointing to the node that is the direct predecessor of the next pair. So you just need to move up one step: temp = temp-&gt;next;

  • Your code makes at the most 5 assignments to either a prev or next pointer. This should be alarming you. When swapping 2 neighboring nodes, there are up to 4 nodes impacted: the two nodes themselves, the successor after the pair, and the predecessor before the pair. When these 4 nodes have been put in their right order, there are 3 connections that are impacted in both directions, so there could be up to 6 pointers that need to be updated. You're missing one update. It is the update of the next pointer that belongs to the predecessor.

  • Your code is accessing temp2-&gt;next without ensuring that temp2 is not null. This could happen when your list has an odd number of nodes. I would suggest changing your while condition so that it assert there is a pair of nodes.

Here is the corrected code:

void swapAdjacent() {
node *temp = head;
while (temp &amp;&amp; temp-&gt;next) { // Require that we have a pair
node *temp1 = temp;
node *temp2 = temp-&gt;next;
temp1-&gt;next = temp2-&gt;next;
if (temp1-&gt;next) { // Must change also in opposite direction
temp1-&gt;next-&gt;prev = temp1;
}
temp2-&gt;prev = temp1-&gt;prev;
if (temp1-&gt;prev) {
temp1-&gt;prev-&gt;next = temp2;
}
temp1-&gt;prev = temp2;
temp2-&gt;next = temp1;
if (temp == head) {
head = temp2;
}
temp = temp-&gt;next; // Only a single step is needed
}
}

答案2

得分: 0

感谢大家的反馈。我找出了我的代码有什么问题,基本上是我忘了更新下一个节点的指针(prev变量)。此外,我多前进了一个节点。以下是我的更新后的代码。我欢迎大家的反馈。

#include <iostream>
using namespace std;

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

node *head = NULL; 

node* getNewNode (int i){
node *newNode = new node;  //在堆中分配动态内存
newNode->data = i;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}

void InsertAtHead(int i){
node *newNode = getNewNode(i);
if (head == NULL){    //处理在列表中插入第一个节点
    head =  newNode;
    return;
}
newNode->next = head;
head->prev = newNode;
head = newNode;    
}

void swapAdjacent() {
node *temp = head;
while (temp != NULL && temp->next!=NULL ) {
    node *temp1 = temp;
    node *temp2 = temp->next;
     if(temp2->next != NULL){
        temp2->next->prev = temp1;
    }
    temp1->next = temp2->next;
    temp2->prev = temp1->prev;
    if (temp1->prev != NULL) {
        temp1->prev->next = temp2;
    }
    temp1->prev = temp2;
    temp2->next = temp1;
   
    if (temp == head) {
        head = temp2;
    }
   
    temp = temp->next;
}
}

void display (){
node *temp = head;
while (temp != NULL){
    cout  <<temp->data << '\t';
    temp = temp->next;    
}
cout << '\n';
}

int main (){
InsertAtHead(8); 
InsertAtHead(4);
InsertAtHead(12);
InsertAtHead(3);
InsertAtHead(-8);
InsertAtHead(7);
cout << "原始列表为: " << endl;
display();
swapAdjacent();
cout << "交换相邻元素后的列表: " << endl;
display();
   
return 0;
}

希望这个翻译对您有帮助。如果您有任何其他问题,请随时提出。

英文:

Thanks everyone for your feedback. I figure out what was wrong with my code which basically I forget to update the pointer of the next node (prev variable).Also, I was going forward one node extra. Here is my updated code. I welcome all of your feedback.

#include &lt;iostream&gt;
using namespace std;
struct node {
int data; 
node *prev;
node *next;
};
node *head = NULL; 
node* getNewNode (int i){
node *newNode = new node;  //allocate a dynamic memory in the heap
newNode-&gt;data = i;
newNode-&gt;prev = NULL;
newNode-&gt;next = NULL;
return newNode;
}
void InsertAtHead(int i){
node *newNode = getNewNode(i);
if (head == NULL){    //addressing inserting the first node in the list.
head =  newNode;
return;
}
newNode-&gt;next = head;
head-&gt;prev = newNode;
head = newNode;    
}
void swapAdjacent() {
node *temp = head;
while (temp != NULL &amp;&amp; temp-&gt;next!=NULL ) {
node *temp1 = temp;
node *temp2 = temp-&gt;next;
if(temp2-&gt;next != NULL){
temp2-&gt;next-&gt;prev = temp1;
}
temp1-&gt;next = temp2-&gt;next;
temp2-&gt;prev = temp1-&gt;prev;
if (temp1-&gt;prev != NULL) {
temp1-&gt;prev-&gt;next = temp2;
}
temp1-&gt;prev = temp2;
temp2-&gt;next = temp1;
if (temp == head) {
head = temp2;
}
temp = temp-&gt;next;
}
}
void display (){
node *temp = head;
while (temp != NULL){
cout  &lt;&lt;temp-&gt;data &lt;&lt; &#39;\t&#39;;
temp = temp-&gt;next;    
}
cout &lt;&lt; &#39;\n&#39;;
}
int main (){
InsertAtHead(8); 
InsertAtHead(4);
InsertAtHead(12);
InsertAtHead(3);
InsertAtHead(-8);
InsertAtHead(7);
cout &lt;&lt; &quot;The original list is: &quot; &lt;&lt; endl;
display();
swapAdjacent();
cout &lt;&lt; &quot;The list after swapping the adjacent elements is: &quot; &lt;&lt; endl;
display();
return 0;
}

huangapple
  • 本文由 发表于 2023年2月27日 02:16:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75574080.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定