List that contains only the elements of the one of the two given lists

In summary: This is unnecessary.3. q = q->next; 4. if q is null: 5. if M3==NULL: 6. M3->data = p->data; 7. else: 8. M3=M3->next; 9. p = p->next; 10. return M3; In summary, the algorithm creates a new list by assigning the elements of the first list that don't exist in the second list.
  • #1
evinda
Gold Member
MHB
3,836
0
Hi! (Smile)

Given two sorted lists $M_1, M_2$, I want to write an algorithm, that creates a new list $M_3$, that contains the elements of $M_1$, that do not exist in $M_2$.

That's what I have tried:

Code:
Algorithm(M1,M2){
    pointer q=M1, p=M2, M3;
    int same=0;
    if (M1==NULL) return error;
    else if (M2==NULL) return M1;

    while (q!=NULL){
            while (p!=NULL){
                    if (p->data==q->data){
                       same=1;
                    }
                    p=p->next;
            }
            if (same==0){
                M3=q;
                M3=M3->next;
            }
            q=q->next;
    }   
    return M3;

Could you tell me if it is right or if I have done something wrong? (Thinking)
Is there also a better way to do this? :confused:
 
Technology news on Phys.org
  • #2
This is wrong. First, you never create a new list M3; you only assign to M3 some tail of (tail of tail of...) M1. Second, you never use comparison and therefore ignore the fact that the lists are sorted.

P.S. Don't put a comma before "that". See http://www.grammarly.com/handbook/punctuation/comma/28/comma-setting-off-restrictive-clauses/.
 
  • #3
Evgeny.Makarov said:
This is wrong.
So, is it totally wrong? (Worried)

Evgeny.Makarov said:
First, you never create a new list M3; you only assign to M3 some tail of (tail of tail of...) M1. Second, you never use comparison and therefore ignore the fact that the lists are sorted.

How can we create then a new list? (Thinking)

Is it possible that we write an algorithm with time complexity $O(n+m)$, where $n$ is the number of elements of $M_1$ and $m$ is the number of elements of $M_2$?
Evgeny.Makarov said:
P.S. Don't put a comma before "that". See http://www.grammarly.com/handbook/punctuation/comma/28/comma-setting-off-restrictive-clauses/.

Ok... (Nod)
 
  • #4
evinda said:
So, is it totally wrong?
I am afraid so.

evinda said:
How can we create then a new list?
For this you need to create a new record with fields [m]data[/m] and [m]next[/m]. I have not been following your other threads, so I am not sure how this is done in your programming language.

evinda said:
Is it possible that we write an algorithm with time complexity $O(n+m)$, where $n$ is the number of elements of $M_1$ and $m$ is the number of elements of $M_2$?
That's the idea. To do this, you need to use the fact that the lists are sorted.

I recommend considering several example lists and figuring out how the algorithm should work in those examples. Then formulate the general algorithm.
 
  • #5
I tried this:
Code:
Algorithm(M1,M2){
  pointer p=M1, q=NULL, M3=NULL;
  while (p!=NULL){
           q=M2;
           while (q->data<p->data and q!=NULL){
                    q=q->next;
            }
            if (q->data!=p->data){
               if (M3==NULL) M3->data=p->data;
               else{
                      M3= M3->next
                      M3->data=p->data;
               }
            }
            p=p->next;
   }
}
But now the time complexity is $O(n \cdot m)$ instead of $O(n+m)$, right?
What could I change? (Thinking)
 
  • #6
Evinda,
I'm afraid you're doomed to continue making errors until you're willing to let the computer help you by implementing your ideas with a real programming language.

1. while (q->data < p->data and q != null): If q is null, this won't work in any programming language that I know. If the language has "shortcut" evaluation (C++ or Java), you need to change the order of the conditions.

2. if (M3 == null) M3->data=p->data:
This fails period.

3. M3=M3->next;
M3->data=p->data; :
Even if somehow this would make sense, at the end of your algorithm, you have no way of accessing the created difference.

Following is a complete solution in C++. Notice to test the solution, you need to have sorted lists. The testing of all possible situations is an art; I think you ought to become familiar with this testing problem.

Code:
#include <cstdlib>
#include <cstddef>
#include <iostream>
#include <cmath>
#include <iomanip>

using namespace std;

/* class Node is as specified.  The linked lists are singly linked with no
 * header node.
 */

class Node {
public:
  int data;
  Node* next;
  Node():data(0),next(0){};
  Node(int x):data(x),next(0){};
};

/*  Makes a sorted linked list of nodes with "random" data fields.  This list
 * represents a multiset; i.e. not all data fields need be different.  The list
 * is created (for n != 0) by first creating a node with random data and then 
 * inserting a new node with random data into its proper position.
 */
Node* makeSortedList(int n) {
  if (n == 0) {
    return(NULL);
  }
  Node *first, *p, *q, *r;
  int x = rand() % 100, i;
  first = new Node(x);
  for (i = 1; i < n; i++) {
    x = rand() % 100;
    r = new Node(x);
    q = NULL;
    p = first;
    while (p != NULL && p->data < x) {
      q = p;
      p = p->next;
    }
    if (q == NULL) {
      r->next = first;
      first = r;
    } else {
      r->next = q->next;
      q->next = r;
    }
  }
  return (first);
}

/*  Just displays a list for debugging purposes.
 */
void printList(Node* first) {
  cout << "{";
  while (first != NULL) {
    cout << first->data << ", ";
    first = first->next;
  }
  cout << "}" << endl;
}

/* Upon entry A and B point to sorted "multiset" lists of size m and n, 
 * respectively.  This computes and returns a new list, the "multiset"
 *  difference A - B. The algorithm is "obviously" of order  m + n.
 */
Node* AminusB(Node* A, Node* B) {
  Node *first, *p = A, *q, *pB = B;
  first = NULL;
  if (A == NULL) {
    return (first);
  }
  while (pB != NULL) {
    while (p != NULL && p->data < pB->data) {
      if (first == NULL) {
        first = new Node(p->data);
        q = first;
      } else {
        q->next = new Node(p->data);
        q = q->next;
      }
      p = p->next;
    }
    if (p == NULL) {
      return (first);
    }
    if (p->data == pB->data) {
      p = p->next;
    }
    pB = pB->next;
  }
  if (first == NULL) {
    first = new Node(p->data);
    q = first;
    p = p->next;
  }
  while (p != NULL) {
    q->next = new Node(p->data);
    q = q->next;
    p = p->next;
  }
  return (first);
}

int main(int argc, char** argv) {
  Node *M1, *M2, *M3;
  M1 = makeSortedList(10);
  printList(M1);
  M2 = makeSortedList(15);
  printList(M2);
  M3 = AminusB(M1, M2);
  printList(M3);
  return 0;
}
 
  • #7
johng said:
1. while (q->data < p->data and q != null): If q is null, this won't work in any programming language that I know. If the language has "shortcut" evaluation (C++ or Java), you need to change the order of the conditions.

So we could also just change the order of the conditions at a pseudocode, or not?

johng said:
3. M3=M3->next;
M3->data=p->data; :
Even if somehow this would make sense, at the end of your algorithm, you have no way of accessing the created difference.
So should the algorithm look like that?

Code:
Algorithm(M1,M2){
  pointer p=M1, q=NULL, M3=NULL, k=NULL;
  while (p!=NULL){
           q=M2;
           while (q->data<p->data and q!=NULL){
                    q=q->next;
            }
            if (q->data!=p->data){
               if (k==NULL) k->data=p->data;
               else{
                      k= k->next;
                      k->data=p->data;
               }
            }
            p=p->next;
   }
   M3=k;
   return M3;
}

johng said:
Following is a complete solution in C++. Notice to test the solution, you need to have sorted lists. The testing of all possible situations is an art; I think you ought to become familiar with this testing problem.

Code:
#include <cstdlib>
#include <cstddef>
#include <iostream>
#include <cmath>
#include <iomanip>

using namespace std;

/* class Node is as specified.  The linked lists are singly linked with no
 * header node.
 */

class Node {
public:
  int data;
  Node* next;
  Node():data(0),next(0){};
  Node(int x):data(x),next(0){};
};

/*  Makes a sorted linked list of nodes with "random" data fields.  This list
 * represents a multiset; i.e. not all data fields need be different.  The list
 * is created (for n != 0) by first creating a node with random data and then 
 * inserting a new node with random data into its proper position.
 */
Node* makeSortedList(int n) {
  if (n == 0) {
    return(NULL);
  }
  Node *first, *p, *q, *r;
  int x = rand() % 100, i;
  first = new Node(x);
  for (i = 1; i < n; i++) {
    x = rand() % 100;
    r = new Node(x);
    q = NULL;
    p = first;
    while (p != NULL && p->data < x) {
      q = p;
      p = p->next;
    }
    if (q == NULL) {
      r->next = first;
      first = r;
    } else {
      r->next = q->next;
      q->next = r;
    }
  }
  return (first);
}

/*  Just displays a list for debugging purposes.
 */
void printList(Node* first) {
  cout << "{";
  while (first != NULL) {
    cout << first->data << ", ";
    first = first->next;
  }
  cout << "}" << endl;
}

/* Upon entry A and B point to sorted "multiset" lists of size m and n, 
 * respectively.  This computes and returns a new list, the "multiset"
 *  difference A - B. The algorithm is "obviously" of order  m + n.
 */
Node* AminusB(Node* A, Node* B) {
  Node *first, *p = A, *q, *pB = B;
  first = NULL;
  if (A == NULL) {
    return (first);
  }
  while (pB != NULL) {
    while (p != NULL && p->data < pB->data) {
      if (first == NULL) {
        first = new Node(p->data);
        q = first;
      } else {
        q->next = new Node(p->data);
        q = q->next;
      }
      p = p->next;
    }
    if (p == NULL) {
      return (first);
    }
    if (p->data == pB->data) {
      p = p->next;
    }
    pB = pB->next;
  }
  if (first == NULL) {
    first = new Node(p->data);
    q = first;
    p = p->next;
  }
  while (p != NULL) {
    q->next = new Node(p->data);
    q = q->next;
    p = p->next;
  }
  return (first);
}

int main(int argc, char** argv) {
  Node *M1, *M2, *M3;
  M1 = makeSortedList(10);
  printList(M1);
  M2 = makeSortedList(15);
  printList(M2);
  M3 = AminusB(M1, M2);
  printList(M3);
  return 0;
}

I will take a look at it..
 

FAQ: List that contains only the elements of the one of the two given lists

What is the purpose of a list that contains only the elements of one of two given lists?

The purpose of this type of list is to simplify data by combining the elements from two separate lists into one organized list. This can make it easier to analyze and manipulate the data.

How is a list that contains only the elements of one of two given lists different from a regular list?

A regular list may contain elements from multiple sources, whereas a list that contains only the elements of one of two given lists will only include elements from one source. Additionally, the elements in this type of list may be organized or filtered in a specific way depending on the criteria used to create the list.

What types of data can be included in a list that contains only the elements of one of two given lists?

Any type of data that can be organized into a list can be included in this type of list. This can include numerical data, text, or even more complex data such as images or audio files.

How can a list that contains only the elements of one of two given lists be created?

This type of list can be created using a variety of methods, depending on the tools and software available. One common way is to use programming languages such as Python or R to filter and combine data from two separate lists into one list. Other software or tools may have specific functions or features for creating this type of list as well.

What are some potential uses for a list that contains only the elements of one of two given lists?

This type of list can be useful in many different scenarios, such as data analysis, data visualization, or data manipulation. For example, a scientist studying the effects of a certain treatment on a group of patients may use this type of list to combine data from two different sources, such as patient medical records and treatment logs, to analyze the results. It can also be used to simplify data for presentation or to identify patterns or trends in the data.

Similar threads

Replies
25
Views
2K
Replies
2
Views
2K
Replies
7
Views
3K
Replies
3
Views
1K
Replies
2
Views
1K
Replies
9
Views
2K
Replies
29
Views
4K
Back
Top