my exercise is to read 2 simple chained lists from 2 files:
F1:
1 2 3 4 5 6 7 8
F2:
6 7 8 9 10
Then list the common values and also list the union of the 2 structures. This is the code until now:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int key;
struct node *next;
} NodeT, NodeT2, NodeTcom, NodeTuni;
NodeT *search(NodeT *head, int givenKey)
{
//TODO: search the given key and return the first node containing it or NULL
while (head != NULL)
{
if (head -> key == givenKey)
{
return head;
}
else
{
head = head->next;
}
}
return NULL;
}
void print_list(NodeT *head)
{
//TODO: print list keys
if (head == NULL)
printf("Empty list!");
else
while (head != NULL)
{
printf("%d ", head->key);
head = head->next;
}
printf("\n");
}
void insert_last(NodeT **head, NodeT **tail, int givenKey)
{
//TODO: insert the given key in the last position of the list given by head and tail;
NodeT * p = (NodeT*)malloc(sizeof(NodeT));
p->key = givenKey;
p->next = NULL;
if (*tail == NULL)
{
*head = *tail = p;
}
else
{
(*tail)->next = p;
*tail = p;
}
}
void uniune(NodeTuni **headU, NodeTuni **tailU, NodeT *head){
while (head != NULL)
{
//printf("%d", head->key);
insert_last(**headU, **tailU, head->key);
head = head->next;
}
}
int main()
{
///PRIMA LISTA
NodeT *first = NULL;
NodeT *last = NULL;
FILE *fp;
fp = fopen("E:\\F1.txt", "r");
int temporary;
while( fscanf(fp, "%d", &temporary) > 0)
{
insert_last(&first, &last, temporary);
}
fclose(fp);
printf("Prima lista:");
print_list(first);
///A DOUA LISTA
NodeT2 *first2 = NULL;
NodeT2 *last2 = NULL;
FILE *fp2;
fp2 = fopen("E:\\F2.txt", "r");
while( fscanf(fp2, "%d", &temporary) > 0)
{
insert_last(&first2, &last2, temporary);
}
fclose(fp2);
printf("A doua lista:");
print_list(first2);
//PARTEA DE VERIFICARE DUBLU:
///LISTA UNITA
NodeTuni *firstU = NULL;
NodeTuni *lastU = NULL;
uniune(&firstU, &lastU, first);
printf("Lista comuna:");
print_list(firstU);
return 0;
}
The uniune function is not working. My problem is that I don't know how to use correctly pointers. Any type of help is appreciated (possible with concrete code).
CodePudding user response:
- You do not have to
typedef
multiple types. It is meaningless and just confusing. - You do not have to use
tail
as long as you always append a new node to the last position of the list. - It will be better to choose
*node
, not**node
as the type
of the arguments to theinsert_last()
. It is related to the return value ofinsert_last()
mentioned below. - Instead
insert_last()
should return the pointer to the created list. Then you can make the recursion easy.
Then would you please try:
#include <stdio.h>
#include <stdlib.h>
#define FILE1 "E:\\F1.txt"
#define FILE2 "E:\\F2.txt"
typedef struct node {
int key;
struct node *next;
} node;
node *search(node *head, int givenKey)
{
//TODO: search the given key and return the first node containing it or NULL
while (head != NULL) {
if (head->key == givenKey) {
return head;
} else {
head = head->next;
}
}
return NULL;
}
void print_list(node *head)
{
//TODO: print list keys
if (head == NULL) {
printf("Empty list!\n");
return;
}
while (head != NULL) {
printf("%d ", head->key);
head = head->next;
}
printf("\n");
}
node *insert_last(node *head, int givenKey)
{
//TODO: insert the given key in the last position of the list given by head
// return the first node
if (head == NULL) {
node *p = malloc(sizeof(node));
if (p == NULL) return head;
p->key = givenKey;
p->next = NULL;
return p;
} else {
head->next = insert_last(head->next, givenKey);
return head;
}
}
node *common(node *head1, node *head2)
{
// create a new list of common values of head1 and head2
// return the first node
if (head1 == NULL || head2 == NULL) {
printf("Empty list!\n");
return NULL;
}
node *p = NULL; // create a new list
while (head1 != NULL) {
if (search(head2, head1->key)) { // if found in both lists
p = insert_last(p, head1->key); // then append to the new list
}
head1 = head1->next;
}
return p;
}
node *uniune(node *head1, node *head2)
{
// create a new list of union values of head1 and head2
// return the first node
node *p = NULL; // create a new list
while (head1 != NULL) {
if (! search(p, head1->key)) { // copy new values of head1
p = insert_last(p, head1->key);
}
head1 = head1->next;
}
while (head2 != NULL) {
if (! search(p, head2->key)) { // copy new values of head2
p = insert_last(p, head2->key);
}
head2 = head2->next;
}
return p;
}
void free_list(node *head)
{
// free the nodes of the list recursively
if (head == NULL) return;
free_list(head->next);
free(head);
}
int main()
{
///PRIMA LISTA
node *first1 = NULL;
FILE *fp1 = fopen(FILE1, "r");
if (fp1 == NULL) {
fprintf(stderr, "cannot open %s\n", FILE1);
exit(1);
}
int temporary;
while (fscanf(fp1, "%d", &temporary) > 0) {
first1 = insert_last(first1, temporary);
}
fclose(fp1);
printf("Prima lista: ");
print_list(first1);
///A DOUA LISTA
node *first2 = NULL;
FILE *fp2 = fopen(FILE2, "r");
if (fp2 == NULL) {
fprintf(stderr, "cannot open %s\n", FILE2);
exit(1);
}
while (fscanf(fp2, "%d", &temporary) > 0) {
first2 = insert_last(first2, temporary);
}
fclose(fp2);
printf("A doua lista: ");
print_list(first2);
node *first3 = NULL;
first3 = common(first1, first2);
printf("Lista comuna: ");
print_list(first3);
node *first4 = NULL;
first4 = uniune(first1, first2);
printf("Lista unita: ");
print_list(first4);
free_list(first1);
free_list(first2);
free_list(first3);
free_list(first4);
return 0;
}
Output:
Prima lista: 1 2 3 4 5 6 7 8
A doua lista: 6 7 8 9 10
Lista comuna: 6 7 8
Lista unita: 1 2 3 4 5 6 7 8 9 10