在类上链接列表中交换节点

时间:2015-04-03 11:19:16

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

我的问题是,在运行程序之后,我在交换之后获得的唯一内容是head元素和列表的第3个元素,无论我交换哪个元素。

代码:

#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 ++中的新手。

2 个答案:

答案 0 :(得分:0)

你需要添加一些处理你要交换的元素之后的情况。

查看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:....

等等。

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

我可以为你提供代码,但我想你会通过自己解决这个问题来学习更多知识。

答案 1 :(得分:0)

在您的Swap方法中,我做了两处更改。首先,我使参数只是指针而不是双指针。这是因为如果你不小心,你可能会失去对元素的追踪。第二个是我将'tmp'变量移动了几行,因为交换前一个节点的行可以在之前 - >接下来不同。 所以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;
}

希望有所帮助!