Function that can swap elements in a singly linked list

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Bito
    New Member
    • Mar 2010
    • 3

    Function that can swap elements in a singly linked list

    Some one help me write a function that can swap elements in a singly linked list?Having a problem swapping the elements without, loosing some of the data?
  • slavik262
    New Member
    • Mar 2010
    • 5

    #2
    Assuming you can get pointers to the data of the two nodes you want to swap (call them a and b), I'd do the following:
    1. In your function, create a variable to temporarily hold the value of b (if you're using an int, int temp = b).
    2. Assign the value of a to the value of b (b = a).
    3. Assign the value of a to the temporary variable (a = temp).

    Comment

    • jkmyoung
      Recognized Expert Top Contributor
      • Mar 2006
      • 2057

      #3
      It's a little more complicated then that! You need to switch 4 links altogether. link to a, link from a, link to b, link from b.

      What you need to do is find the nodes before them. Say your nodes are a, b.
      Find the nodes linking to them, say beforeA, beforeB.

      beforeA.next = b;
      beforeB.next = a;
      So now you've switched the links to them. Now, you must switch the links after the nodes.
      temp = a.next;
      a.next = b.next;
      b.next = temp;

      Also, you have to take into account: what if there is no beforeA, or beforeB? (eg one of them is the head?) See how this works out, and then try to figure out your special cases. Don't forget to check if a = b; then you don't have to do any work!

      Comment

      • slavik262
        New Member
        • Mar 2010
        • 5

        #4
        What is the necessity of swapping the nodes themselves? While swapping the values isn't truly the same as swapping the nodes, the end result is the same without all the extra pointer assignments.

        A check to see if a already equals b would save you a lot of time though.

        Comment

        • jkmyoung
          Recognized Expert Top Contributor
          • Mar 2006
          • 2057

          #5
          I guess it depends on the composition of the nodes; whether the data is easily copyable or depends on the context of the node.

          Bito, give us more info as to how you're storing your linked list, or what std library class you're using.

          Comment

          • slavik262
            New Member
            • Mar 2010
            • 5

            #6
            Ah, so you're saying that it might be faster to swap the pointers around if the data stored in the linked list is a complex type like a class.

            Comment

            • weaknessforcats
              Recognized Expert Expert
              • Mar 2007
              • 9214

              #7
              This is not that hard.

              If you have node addresses A B C D and you want to swap B and C what you do is:

              1) Traverse to B. During this traverse, save the address of the current node in TEMP before you go the the next node. When you get to B, TEMP will have the address of A.

              2) TEMP->NEXT (remember TEMP is the address of A) is assigned B->NEXT. Now you have A pointing to C.

              3) B->NEXT is assigned B->NEXT->NEXT (B->NEXT is C. Therefore,
              B->NEXT->NEXT is really C->NEXT,which is D).

              It looks like this:

              TEMP->NEXT = B->NEXT;
              B->NEXT = B->NEXT->NEXT;

              Comment

              • slavik262
                New Member
                • Mar 2010
                • 5

                #8
                Right, but the point we were discussing before was that if you have a simple data type, it would be faster and simpler to just swap out the values of the nodes.

                Comment

                • Bito
                  New Member
                  • Mar 2010
                  • 3

                  #9
                  Am trying to write a program that prompts the user to enter integer data, i store it in a linked list then i sort it into ascending order. Am using the selection sort function to arrange the data and its supposed to call the swap function, i want to swap the last and largest element in the linked list. but i do not know how to write that function.these are my two functions to find the last and largest elements in the linked list
                  Code:
                  Node * maxPtr(Node * &list,int n)
                  {
                      int i = 0; 
                      Node * mPtr = list;
                      Node * iPtr = list -> next;
                      while( i< n)
                      {
                             if(iPtr -> data > mPtr -> data)
                                {
                                     mPtr = iPtr;
                                }
                                i++;
                                iPtr = iPtr ->next;
                     }
                     return mPtr;
                  }
                  
                  Node * lastPtr(Node * &list,int n)
                  {
                      Node * newp = list;
                      Node * lastp;
                      int i = 0;
                      while(i < n)
                        {
                       if(newp -> next  == NULL)
                          lastp = newp;
                        }
                        i++;
                        newp = newp -> next;
                        return lastp;
                        
                  }
                  Am left with writing the swap function and need help with that..

                  Comment

                  • Banfa
                    Recognized Expert Expert
                    • Feb 2006
                    • 9067

                    #10
                    In my experience if you are receiving a series of values and storing them in a list that finally has to be ordered it is often just as easy to put them in the list in the right order in the first place as to sort the list after you have all the values.

                    Comment

                    • Bito
                      New Member
                      • Mar 2010
                      • 3

                      #11
                      so how would i be able to do that?? and can u help me with this invariance questionas well..

                      What is the invariance of the algorithm??

                      int power(int n, int p)
                      // Pre: p >= 0
                      // Post: returns n raised to the power p
                      {
                      int result = 1;
                      int i = 0;
                      while (i != p)
                      {
                      result = result * n;
                      i++;
                      }
                      return result;
                      }

                      am abit confused on what we are supposed to do.. Is it right to say that the invariance is n^p since we are going to multiply n by its self n times??

                      Comment

                      • weaknessforcats
                        Recognized Expert Expert
                        • Mar 2007
                        • 9214

                        #12
                        Originally posted by slavik262
                        Right, but the point we were discussing before was that if you have a simple data type, it would be faster and simpler to just swap out the values of the nodes.
                        How do you know this would be faster?

                        If you have an int, that would be the size of a pointer. Swapping trhe int and swapping the next pointer of the nodes is about the same.

                        Swapping floating point will be very much slower. The variables are bigger and have rounding considerations.

                        Swapping char will cause a conversion to int and then a conversion back to char.

                        Comment

                        • jkmyoung
                          Recognized Expert Top Contributor
                          • Mar 2006
                          • 2057

                          #13
                          I agree with Banfa. Construct your single linked list one by one, but have your AddNode function check the values.
                          eg. pseudo
                          Code:
                          void addNode(newNodeValue){
                          int newNodeValue;
                          Node newNode = new Node(newNodeValue);
                          Node curr, next;
                          curr = head;
                          if (curr == null){ 
                            head = newNode;
                            return;
                          }
                          if (curr.value > newNodeValue){
                             next = head;
                             head = newNode;
                             head.next = next;
                             return;
                          }  
                          next = curr.next();
                          while (next != null && next.value < newNodeValue){
                            curr = next;
                            next = curr.next;
                          }
                          curr.next = newNode;
                          if(next != null){// end of list
                            newNode.next = next;
                          }

                          Comment

                          • weaknessforcats
                            Recognized Expert Expert
                            • Mar 2007
                            • 9214

                            #14
                            Actually, I would improve this by writing a function with two arguments that are pointers to node that would insert the second pointer after the first pointer in the list.

                            What this will do is isolate all this next/prev pointer fiddling to one function. Call that function from your AddNode.

                            Note that ot insert at the front of the list, you add your insert-after function using the adress of the first node in the list as the second argument.

                            Then, write a second function to create a new node on the heap and return a pointer to that node. This function will have the value of the node as the first argument.

                            Your AddNode would start to look like:

                            Code:
                            void AddNode(NewValue)
                            {
                            
                            Node* temp = FindEndOFList();         //write this too
                            Node* newNode = CreateNode(NewValue);
                            InsertAfter(temp, newNode);
                            }
                            By having your functions do only one thing, you can use them more often.

                            Comment

                            • jkmyoung
                              Recognized Expert Top Contributor
                              • Mar 2006
                              • 2057

                              #15
                              In response to post 11: Sorry, do you have another definition of invariance? It sounds like what wouldn't change in the function regardless of the values of p and n.

                              In response to post 12: Switching links requires at most 4 link switches, as well as a lot of special case testing.

                              In response to post 14: Then the insertions would not be sorted. The only reason for post 13 was for sorted insertion. Could write a simplifying function called Node FindGreatestNod eLessThan(int value), which returns the last node with value smaller than the given value. eg:
                              Code:
                              void addNode(int newValue){
                                Node newNode = new Node(newValue);
                                Node last = FindGreatestNodeLessThan(newValue);
                                if( last == null){
                                   newNode.next = head;
                                   head = newNode;
                                   return;
                                }
                                newNode.next = last.next;
                                last.next = newNode;
                              }
                              But this is only useful if FindGreatestNod eLessThan can be reused somewhere. The function FindGreatestNod eLessThan would require pointer swapping anyways.

                              Comment

                              Working...