Algorithm for Ordering Odds & Evens in Linked List L

In summary: Yes, that is correct. The function rearrange only appends the odd nodes to L3 and then appends the even nodes in their original order afterwards. This ensures that the final list L' has all odd nodes before even nodes, while maintaining the original order of odd and even nodes.
  • #1
evinda
Gold Member
MHB
3,836
0
Hello! (Wave)

Consider a singly-linked list [m] L[/m] each element of which is a struct with two fields, an integer [m]num[/m] and a pointer [m]next[/m] to the next element of the list.

Describe an algorithm that gets as argument a pointer to the first element of the list [m]L[/m] and that creates a new list [m]L'[/m] that will contain all the elements of [m]L[/m] ordered in the following way:

The elements of [m]L[/m] for which the field [m]num[/m] is an odd number have to appear in [m]L'[/m] before all the elements of which the field [m]num[/m] is an even number. The elements with an odd number at the field [m]num[/m] should keep in [m]L'[/m] the display order that they had at the initial list [m]L[/m].

The same should hold for the elements with an even number at the field [m]num[/m].

For example, if the initial list is [m]L=13->15->20->17->24->26->9->30->53->44[/m] the final list should be [m]L'=13->15->17->9->53->20->24->26->50->44[/m].That's what I have tried:

Code:
   List(L){
      if (L==NULL) return;
      node *p=NULL, *q=L, *l=L, *L3=NULL, *head2=NULL, *tail1=NULL, *tail2=NULL;
      while (q!=NULL){
            if (q-> num mod 2==1){
                if (p==NULL){
                   p->num=q->num;
                   L3=p;
                }
                else {
                   p=p->next;
                   p->num=q->num;
               }
            }
      }
      tail=p;
      while (l!=NULL){
            if (l-> num mod 2==0){
               if (l==NULL){
                   l->num=q->num;
                   head2=l;
                }
                else {
                   l=l->next;
                   l->num=q->num;
               }
            }
      }
      tail2=q;
      tail1->next=head2;
      tail1=tail2;
      return L3;
   }
Could you tell me if it is right?
 
Technology news on Phys.org
  • #2
Evinda,
No, it's not right. You continue to make the error of referencing a field of a null pointer. However, your main idea is okay. You traverse the list L twice with the first traversal appending all "odd" nodes to an initially empty list L3, and the second traversal appending the "even" nodes to L3. So your first while loop is pretty much correct. I could make no sense of the second while loop.
Here's a complete solution using your idea:
Code:
class Node {
public:
  int num;
  Node* next;

  Node(int v) : num(v), next(0) {
  }
};

Node* makeList(int a[], int n) {
  if (n == 0) {
    return (NULL);
  }
  int i;
  Node* first = new Node(a[0]), *p = first;
  for (i = 1; i < n; i++) {
    p->next = new Node(a[i]);
    p = p->next;
  }
  return (first);
}

Node* rearrange(Node* L) {
  Node* L3 = NULL, *p, *q;
  if (L == NULL) {
    return (NULL);
  }
  int i;
  for (i = 1; i >=0; i--) {
    q = L;
    while (q != NULL) {
      if (q->num % 2 == i) {
        if (L3 == NULL) {
          L3 = new Node(q->num);
          p = L3;
        } else {
          p->next = new Node(q->num);
          p = p->next;
        }
      }
      q = q->next;
    }
  }
  return(L3);
}

int main(int argc, char** argv) {
  int a[] = {13, 15, 20, 17, 24, 26, 9, 30, 53, 44};
  Node *L = makeList(a, 10), *p = L;
  while (p != NULL) {
    cout << p->num << " ";
    p = p->next;
  }
  cout << endl;
  Node* Lprime = rearrange(L);
  p = Lprime;
  while (p != NULL) {
    cout << p->num << " ";
    p = p->next;
  }
  cout << endl;
  return (0);
}

However, I strongly suspect the exercise meant for you to write a function that traverses the original list only once. This is only slightly more complicated. I advise you to write this function.
 
  • #3
johng said:
Evinda,
No, it's not right. You continue to make the error of referencing a field of a null pointer. However, your main idea is okay. You traverse the list L twice with the first traversal appending all "odd" nodes to an initially empty list L3, and the second traversal appending the "even" nodes to L3. So your first while loop is pretty much correct. I could make no sense of the second while loop.
Here's a complete solution using your idea:
Code:
class Node {
public:
  int num;
  Node* next;

  Node(int v) : num(v), next(0) {
  }
};

Node* makeList(int a[], int n) {
  if (n == 0) {
    return (NULL);
  }
  int i;
  Node* first = new Node(a[0]), *p = first;
  for (i = 1; i < n; i++) {
    p->next = new Node(a[i]);
    p = p->next;
  }
  return (first);
}

Node* rearrange(Node* L) {
  Node* L3 = NULL, *p, *q;
  if (L == NULL) {
    return (NULL);
  }
  int i;
  for (i = 1; i >=0; i--) {
    q = L;
    while (q != NULL) {
      if (q->num % 2 == i) {
        if (L3 == NULL) {
          L3 = new Node(q->num);
          p = L3;
        } else {
          p->next = new Node(q->num);
          p = p->next;
        }
      }
      q = q->next;
    }
  }
  return(L3);
}

int main(int argc, char** argv) {
  int a[] = {13, 15, 20, 17, 24, 26, 9, 30, 53, 44};
  Node *L = makeList(a, 10), *p = L;
  while (p != NULL) {
    cout << p->num << " ";
    p = p->next;
  }
  cout << endl;
  Node* Lprime = rearrange(L);
  p = Lprime;
  while (p != NULL) {
    cout << p->num << " ";
    p = p->next;
  }
  cout << endl;
  return (0);
}

However, I strongly suspect the exercise meant for you to write a function that traverses the original list only once. This is only slightly more complicated. I advise you to write this function.

With the function [m] rearrange [/m] we only append all "odd" nodes to the list L3, right?
 

FAQ: Algorithm for Ordering Odds & Evens in Linked List L

What is an algorithm for ordering odds and evens in a linked list?

An algorithm for ordering odds and evens in a linked list is a set of steps and rules that can be followed to rearrange the elements of a linked list so that all the odd numbers appear before the even numbers. This typically involves traversing the list and moving nodes around.

Why would you need to order odds and evens in a linked list?

Ordering odds and evens in a linked list may be necessary in situations where you need to perform operations on the list that require a specific ordering, such as finding the median or calculating certain statistics. It can also make the list more organized and easier to work with.

How do you implement an algorithm for ordering odds and evens in a linked list?

The implementation of this algorithm may vary depending on the specific programming language and data structure being used. However, a common approach is to traverse the list and use temporary variables to keep track of the odd and even nodes. The odd nodes are then placed in a new list, followed by the even nodes, and then the new list is linked back to the original list.

What is the time complexity of an algorithm for ordering odds and evens in a linked list?

The time complexity of this algorithm is typically O(n), where n is the number of nodes in the linked list. This is because the algorithm involves traversing the entire list and performing constant time operations on each node.

Can an algorithm for ordering odds and evens in a linked list be optimized?

Yes, there are ways to optimize this algorithm to reduce the time complexity. One approach is to use two pointers, one for odd nodes and one for even nodes, and then rearrange the nodes in place without creating a new list. This can reduce the time complexity to O(1) or constant time.

Similar threads

Replies
2
Views
2K
Replies
7
Views
3K
Replies
9
Views
2K
Replies
1
Views
1K
Replies
1
Views
1K
Replies
1
Views
2K
Replies
1
Views
2K
Back
Top