Thread: Help with Collatz Conjecture program

1. Help with Collatz Conjecture program

For those who do not know what the Collatz Conjecture is:
Collatz conjecture - Wikipedia, the free encyclopedia
Ok so my program works pretty well. There are 2 menu choices. You can either just see the basic hailstone sequence or you print the cycle lengths between any two numbers. In this menu choice, my program is also supposed to find the minimum cycle length and maximum cycle length between the two numbers and print out the the two numbers, as well as their respective integers. This program uses two doubly linked lists to hold the data (one for each menu choice)
The problem I'm having is the printing and/or finding the max/min cycle length.

I think the problem is in this function
Code:
```//comparecycles: This function is for the 1st linked list. It gets the min and max cycle lengths for the double linked list and prints them
//output: an integer
int comparecycles(Node * head, Node * tail)
{
Node * cur;
Node * max;
Node * min;
for(cur = head -> next; cur != tail; cur = cur -> next) //running through nodes
{
if(cur -> cycle_length > max -> cycle_length) //finding the biggest cycle length
{
max = cur;
}
else if(cur -> cycle_length < min -> cycle_length && min -> cycle_length != 0) //finding smallest
{
min = cur;
}
else
{
//do nothing
}
}
printf("The min is %d from %d\n", min -> cycle_length, min -> num);
printf("The max is %d from %d\n", max -> cycle_length, max -> num);
return 0;
}```
Here is the whole program if you wish to compile it (it's long)
Code:
```/*
This program utilizes the Collatz conjecture. The program can input any integer and it can also tell you the cycle length as well. Although, this code might look complex at first. It is quite simple. There are two doubly linked lists going on at once. So there is basically two copies of each function for each doubly linked list. For example there is two addtails and two deletes. Everything to do with Case 2 is marked with a 2. Everything to do with Case 1 is just left alone.
*/

#include <stdio.h>
#include <stdlib.h>

typedef struct node //my node for the 1st case. Listing cycle lengths
{
int cycle_length;
int num;
struct node *prev;
struct node *next;
} Node;

typedef struct node2 //2nd node. This is for the hailstone sequence
{
int num;
struct node2 *prev;
struct node2 *next;
} Node2;

Node * newnode(int number, int cycle); //function prototypes. ill go into details of each below
Node2 * newnode2(int number);
int case1(int start, int finish, Node * head, Node *tail);
int case2(int num, Node2 * head2, Node2 * tail2);
int cycle(int num);
int comparecycles(Node * head, Node * tail);
void printtable(Node * head, Node *tail);
void printnodes(Node2 * head2, Node2 * tail2);

int main()
{
Node * tail;
tail = newnode(0,0);

Node2 * tail2;   //dummy head and tail for 2nd list
tail2 = newnode2(0);

int i = 0; //variables for where to start and end 1st linked list
int j = 0;

int k = 0; //variables for the start of the 2nd linked list
{
printf(">>");
{
case 1:
printf("Enter i\n>>");
scanf("%d", &i);
printf("Enter j\n>>");
scanf("%d", &j);
case1(i,j,head,tail);  //running the case 1 function
break;

case 2:
printf("Enter Number\n>>");
scanf("%d", &k);
case2(k, head2, tail2); //running case 2
break;

case 3:

return 0;
break;

default:
printf("Error");
break;
}
}
return 0;
}

//newnode: This function allocates memory and set data members for the 1st linked list
//input: an integer (the number), a 2nd integer (number of cycles)
//output: pointer to a node
Node * newnode(int number, int cycle) //1st list
{
Node * new;
new = malloc(sizeof(Node)); //allocating memory
new -> num = number;
new -> cycle_length = cycle;
new -> prev = NULL;  //linking
new -> next = NULL;
return new;
}

//newnode2: This function allocates memory and sets data members for the 2nd linked list
//input: an integer (the number)
//output: pointer to a node
Node2 * newnode2(int number) //2nd list
{
Node2 * new;
new = malloc(sizeof(Node)); //allocating memory
new -> num = number;
new -> prev = NULL; //linking
new -> next = NULL;
return new;
}

//input: dummy head and tail node. The new node to be added
//output: the dummy tail node
Node * addtail(Node * head, Node * tail, Node * new)  //1st
{
if(tail -> prev == head) //if list is empty
{
tail -> prev = new;
new -> next = tail;
return tail;
}
else //if list has nodes
{
new -> prev = tail -> prev;
new -> next = tail;
tail -> prev -> next = new;
tail -> prev = new;
return tail;
}
return NULL; //should never reach here
}

Node2 * addtail2(Node2 * head2, Node2 * tail2, Node2 * new) //2nd
{
if(tail2 -> prev == head2) //list is empty
{
tail2 -> prev = new;
new -> next = tail2;
return tail2;
}
else //not empty
{
new -> prev = tail2 -> prev;
new -> next = tail2;
tail2 -> prev -> next = new;
tail2 -> prev = new;
return tail2;
}
return NULL; //just in case
}

//delete: This function deletes all nodes, then starts over like the first lines of main
//output: the current node
Node * delete(Node * head) //1st list
{
Node * cur;
Node * prev;
cur = head -> next -> next;
while(cur != NULL)
{
free(prev);
prev = cur;
cur = cur -> next;
}
free(prev);
Node * tail; //dummy tail node
tail = newnode(0,0);
return cur;
}

//delete2: This function deletes all nodes, then starts over
//output: the cur node
Node2 * delete2(Node2 * head2) //2nd list
{
Node2 * cur;
Node2 * prev;
cur = head2 -> next -> next;
while(cur != NULL)
{
free(prev);
prev = cur;
cur = cur -> next;
}
free(prev); //freeing everything
Node2 * tail2;
tail2 = newnode2(0);
return cur;
}

//case1: This function does everything case 1 needs. adds data members. adds them to the tail of the list, prints the table and frees memory
//input: the start (i), the finish (j), dummy head and tail node
//output: an integer
int case1(int start, int finish, Node * head, Node * tail)
{
for(start; start <= finish; start++)
{
Node * new = newnode(start, cycle(start));
}
return 0;
}

//case2: This function does a lot. Adds data members. Adds nodes to list. Prints nodes and frees memory
//output: An integer
int case2(int num, Node2 * head2, Node2 * tail2)
{
int cycle_length = cycle(num);
Node2 * new = newnode2(num);
while(num !=1)
{
if(num != 1 && num % 2 ==1)
{
num = 3 * num + 1;
Node2 * new = newnode2(num);
}
else if(num != 1 && num % 2 == 0)
{
num = num/2;
Node2 * new = newnode2(num);
}
}
printf("The cycle length is %d\n", cycle_length);
return 0;
}

//cycle: This function is for the 1st and 2nd list. It gets the number of cycle lengths for a number
//input: An integer
//output: the correct cycle length
int cycle(int num)
{
int cycle_length = 0;
while(num != 1)
{
if(num != 1 && num % 2 == 1) //if it is odd
{
num = 3 * num + 1;
}
else if(num != 1 && num % 2 == 0) //even numbers
{
num = num/2;
}
cycle_length++; //increment counter
}
return cycle_length + 1; //including 1
}

//comparecycles: This function is for the 1st linked list. It gets the min and max cycle lengths for the double linked list and prints them
//output: an integer
int comparecycles(Node * head, Node * tail)
{
Node * cur;
Node * max;
Node * min;
for(cur = head -> next; cur != tail; cur = cur -> next) //running through nodes
{
if(cur -> cycle_length > max -> cycle_length) //finding the biggest cycle length
{
max = cur;
}
else if(cur -> cycle_length < min -> cycle_length && min -> cycle_length != 0) //finding smallest
{
min = cur;
}
else
{
//do nothing
}
}
printf("The min is %d from %d\n", min -> cycle_length, min -> num);
printf("The max is %d from %d\n", max -> cycle_length, max -> num);
return 0;
}

//printtable: This prints the table for the 1st linked list
//output: void function
void printtable(Node * head, Node * tail)
{
Node * cur;
{
for(cur = head -> next; cur != tail; cur = cur-> next) //run through nodes
{
printf("%d\t%d\n", cur -> num, cur -> cycle_length); //printing data members
}
}
else //if list is empty
{
printf("Empty List");
}
comparecycles(head, tail); //printing min and max
}

//printnodes: This function prints the hailstone sequence for the 2nd list
//output: void function
void printnodes(Node2 * head2, Node2 * tail2)
{
Node2 * cur;
{
for(cur = head2 -> next; cur != tail2; cur = cur -> next) //run through
{
printf("%d\n", cur -> num); //prints data
}
}
else //if empty
{
printf("Empty List");
}
}

//input: N/A
//output: void
{
printf("1) Caculate cycle lengths between i and j\n");
printf("2) Generate hailstone sequence for any number\n");
printf("3) Exit the program\n");
}```

2. and yes I am aware of the memory leaks so far in this program. I was going to work on freeing up all the memory after I get this little snag done

3. You never initialize max -> cycle_length to any value; same on min.
NOTE: You never allocate space for them either.
NOTE: I suggest turning on your compiler warnings and then pay attention to the warnings.
Code:
`max -> cycle_length`
Tim S.

4. Sweet! Everything works! I got all the memory leaks caught too! Thanks a lot!