【问题标题】:Swapping nodes in linked lists on classes在类的链表中交换节点
【发布时间】:2015-06-08 11:39:29
【问题描述】:

我的问题是,运行程序后,我得到的唯一东西是列表的头元素和第三个元素,无论我要交换哪些元素。

代码:

#include <iostream>
#include <cstdio>
using namespace std;
class List;

class element{
        private:
                int number;
                element* next;
                friend class List;
                friend ostream & operator<<(ostream &,const List &);

        public:
                element(int data){
                        number=data;
                }

                int getData(){
                        return number;
                }

};

class List{
        private:
                element* head;
                int size;
                friend ostream & operator<<(ostream &,const List &);
        public:
                List(){
                        head=NULL;
                        size=0;
                }

                List(const List &lista){
                        //cout << "wyw" << endl;
                        //fflush(stdout);
                        if (lista.size==0){
                                size=0;
                                head=NULL;
                        }
                        else
                        {
                                size=0;
                                head=NULL;
                                element* tmp=lista.head;
                                while(tmp!=NULL){
                                        cout << tmp->number << " ";
                                        fflush(stdout);
                                        this->addToList(tmp->number);
                                        tmp=tmp->next;
                                }
                        }

                }

                ~List(){
                        if (head!=NULL){
                                element* tmp=head;
                                element *temp;
                                while(tmp!=NULL){
                                        temp=tmp->next;
                                        delete tmp;
                                        tmp=temp;
                                }
                                head=NULL;
                        }
                }

                void addToList(int data){
        //              cout << "Ja sie wywolalem" << endl;

                        element* newNode=new element(data);
                        newNode->next=NULL;
                        element *tmp=head;
                        if (tmp!=NULL){
                                while(tmp->next!=NULL){
                                        tmp=tmp->next;
                                }
                                tmp->next=newNode;
                        }
                        else{
                                head=newNode;
                        }
                        size++;

                }

                int popSelected(element *deleted){
                        int value=deleted->number;
                        element* tmp;
                        if (head==deleted){
                                 delete head;
                                 head=NULL;
                        }
                        else
                        {
                                tmp=head;
                                while(tmp->next!=deleted)
                                        tmp=tmp->next;
                                tmp->next=deleted->next;
                                delete deleted;
                                size--;
                        }

                        return value;
                }



                element* getPrevious(element* lol){
                    element* tmp;
                    if (lol==head)
                        return NULL;
                    else{
                        tmp=head;
                        while(tmp->next!=lol)
                            tmp=tmp->next;
                        return tmp;
                    }

                }


                void Swap(element** before, element **ahead){
                    if (head==NULL || (*before)==NULL || (*ahead)==NULL){
                        cout << "Nothing to swap";
                        return;
                    }

                    element* prev=getPrevious(*before);
                    element* prev2=getPrevious(*ahead);
                    element* tmp=(*before)->next;
                    if(prev!=NULL)
                        prev->next=(*ahead);
                    if (prev2!=NULL)
                        prev2->next=(*before);
                    (*before)->next=(*ahead)->next;
                    (*ahead)->next=tmp;
                    if (head==(*before))
                        head=(*ahead);
                    else{
                        if (head==(*ahead))
                            head=(*before);

                    }
                }

                void SortTest(){
                    Swap(&(head->next->next), &(head));
                }



                List& operator=(const List& lista){
                        if (&lista==this) return *this;
                        if (this->head!=NULL){
                                element* tmp=head;
                                element *temp;
                                while(tmp!=NULL){
                                        temp=tmp->next;
                                        delete tmp;
                                        tmp=temp;
                                }
                                head=NULL;
                        }
                        if (lista.size==0){
                                size=0;
                                head=NULL;
                        }
                        else
                        {
                                size=0;
                                head=NULL;
                                element* tmp=lista.head;
                                while(tmp!=NULL){
                                       this->addToList(tmp->number);
                                        tmp=tmp->next;
                                }
                        }

                        return *this;
                }

                List  operator+(const List &lista){
                        List newList;
                        element *tmp=this->head;
                        while (tmp!=NULL){
                                newList.addToList(tmp->number);
                                tmp=tmp->next;
                        }
                        tmp=lista.head;
                        while (tmp!=NULL){
                                newList.addToList(tmp->number);
                                tmp=tmp->next;
                        }
                        return newList;
                }

                bool operator==(const List &lista){
                        if (this->size==lista.size)
                                return true;
                        else
                                return false;
                }

                bool operator>(const List &lista){
                        if (this->size>lista.size)
                                 return true;
                        else
                                return false;
                }

                bool operator<(const List &lista){
                        if (this->size<lista.size)
                                return true;
                        else
                                return false;
                }
};


istream & operator>>(istream &str, List &lists){
        int data;
        str >> data;
        lists.addToList(data);
        return str;
}

ostream & operator<<(ostream &str,const List &lists){
        element*tmp=lists.head;
        if (tmp==NULL){
                str << "List is empty" << endl;
        }
        else{
                while(tmp!=NULL){
                        str <<"(" <<  tmp->number << ")" << "--";
                        tmp=tmp->next;
                }
        str << "NULL" << endl << "Size of list: " << lists.size << endl;
        }
        return str;
}


int main(){
        List lista;
        cin >> lista;
        cin >> lista;
        List list2=lista;
        cout << "Lista nr 1" << endl << lista;
        cout << "Lista nr 2" << endl << list2;
        cin >> list2;
        cout << "Lista nr 2 po zmianie danych" << endl << list2;
        cin >> list2;
        cin >> list2;
        cout << list2 << endl << endl << "Tests!" << endl;
        list2.SortTest();
        cout << list2 << endl;
        //cout << list2;
        return 0;
}

请不要因为这段代码评判我,我完全是 C++ 新手。

【问题讨论】:

    标签: c++ sorting nodes swap singly-linked-list


    【解决方案1】:

    您需要对要交换的元素紧随其后的情况添加一些处理。

    查看 A->B->C 并交换(B, C)

                    element* prev=getPrevious(*before); // prev point to A
                    element* prev2=getPrevious(*ahead); // prev2 point to B
                    element* tmp=(*before)->next;       // tmp point to C
                    if(prev!=NULL)
                        prev->next=(*ahead);            // A->C
                    if (prev2!=NULL)
                        prev2->next=(*before);          // B->B
                    (*before)->next=(*ahead)->next;     // B->NULL
                    (*ahead)->next=tmp;                 // C->C
    

    所以结果是 A->C->C-> .... 而 B 丢失了。

    编辑: OP发表评论后

    您必须一一识别特殊情况。让我们调用元素来交换 A 和 B。

    正常情况(A 和 B 彼此安全远离,而不是一开始):

    prevA = "Element before A"
    nextA = A->next
    prevB = "Element before B"
    nextB = B->next
    
    Swap:
      prevA->next = B
      B->next = nextA
      prevB->next = A
      A->next = nextB
    

    现在您必须考虑特殊情况(并首先处理它们)。

    案例 1:A == B 回来就行了

    案例 2:prevA == NULL

    在这种情况下你需要

    head = B
    

    而不是

    prevA->next = B
    

    案例 3:prevB == NULL

    类似于案例2

    案例 4:nextA == B

    prevA->next = B
    B->next = A
    A->next = nextB
    

    案例 5:nextA == B 和 prevA == NULL

    head = B
    B->next = A
    A->next = nextB
    

    案例 6:..

    等等。

    继续识别所有特殊情况,您最终会得到有效的代码。

    我可以为您提供代码,但我想您会通过自己的工作了解更多信息。

    【讨论】:

    • 好的,但新问题是当我尝试使用不相邻的节点时,我丢失了列表。例如,当我有列表 {5,1,36,4,9,65} 并且我想交换 head(即 5)和 head->next->next->next(即 4)时,交换 i得到 {5,9,65} 仅此而已。我丢失了从一个节点的下一个节点到第二个节点的所有内容。
    【解决方案2】:

    在您的 Swap 方法中,我做了两个更改。首先是我使参数只是一个指针而不是双指针。这是因为如果您不小心,您可能会丢失对元素的跟踪。第二个是我将“tmp”变量移动了几行,因为交换前一个节点的下一个节点的行可能会使 before->next 不同。 所以 Swap 现在是:

    void Swap(element* before, element *ahead){
       if (head == NULL || before == NULL || ahead == NULL){
          cout << "Nothing to swap";
          return;
       }
    
       element* prev = getPrevious(before);
       element* prev2 = getPrevious(ahead);
    
       if (prev != NULL)
          prev->next = ahead;
       if (prev2 != NULL)
          prev2->next = before;
       element* tmp = before->next;
       before->next = ahead->next;
       ahead->next = tmp;
       if (head == before)
          head = ahead;
       else{
          if (head == ahead)
             head = before;
    
       }
    }
    

    所以你的 SortTest 将是:

    void SortTest(){
       Swap(head->next->next, head);
    }
    

    为了测试我使用的主要功能:

    int main(){
       List l;
       l.addToList(1);
       l.addToList(2);
       l.addToList(3);
       l.SortTest();
       cout << l << endl;
    }
    

    希望有帮助!

    【讨论】:

    • 你测试过这个吗?示例:H-&gt;A-&gt;B-&gt;C 和交换(A,B)。所以before=A,ahead=B,prev=H,Prev2=A。现在您执行 1) H->B 和 2) A->A 和 3) tmp=B 和 4) A->C 和 5) B->B。看结果:H->B->B->B->....好像A和C都丢了
    • @nielsen 是的。 A->B->C 和交换(A,B)。所以 before=A,head=B,prev=NULL,Prev2=A。现在您执行 1) A->A 和 2) tmp=A 和 3) A->C 和 4) B->A 和 5) Head=B 所以 H->B->A->C->NULL。您可以尝试使用 SortTest as Swap(head, head->next);与我发布的主要功能。
    • 正确 - 我搞定了。由于第 2 步)A->A 第 3 步将是 tmp=A 而不是 tmp=B 我想。因此,步骤 5 将 B->A 而不是我想的 B->B。所以最后:H->B->A->C。你是对的。
    猜你喜欢
    • 2017-12-07
    • 2018-11-05
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 2015-05-25
    相关资源
    最近更新 更多