Unable to solve: CodeForces (TwoButtons, 520B) by using binary trees - c++

i have been trying to solve this problem by using binary trees, because i am starting to learn about them.
Please tell me if this problem can be solved by using binary trees or not, and if yes, what's wrong with my code for it that i've written so far(its in c++)?
it gives wrong answer...
The Problem:
Vasya has found a strange device. On the front panel of a device there are: a red button, a blue button and a display showing some positive integer. After clicking the red button, device multiplies the displayed number by two. After clicking the blue button, device subtracts one from the number on the display. If at some point the number stops being positive, the device breaks down. The display can show arbitrarily large numbers. Initially, the display shows number n.
Bob wants to get number m on the display. What minimum number of clicks he has to make in order to achieve this result?
Input
The first and the only line of the input contains two distinct integers n and m (1 ≤ n, m ≤ 104), separated by a space .
Output
Print a single number — the minimum number of times one needs to push the button required to get the number m out of number n.
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
struct Node{
int val;
Node* Left;
Node* Right;
};
Node* GetNode(int val){
Node* newnode = new Node();
newnode->val = val;
newnode->Left = NULL;
newnode->Right = NULL;
return newnode;
}
int BFS(Node* root, int m){
int ctr = 0;
queue<Node*> qu;
qu.push(root);
while(!qu.empty()){
Node* tmp = qu.front();
qu.pop();
if(tmp->val == m) return ctr;
ctr++;
if(tmp->Left != NULL) qu.push(tmp->Left);
if(tmp->Right != NULL) qu.push(tmp->Right);
}
}
int main(void){
int n, m;
scanf("%d%d", &n, &m);
Node* root = GetNode(n);
Node* tmp;
queue<Node*> qu;
qu.push(root);
while(!qu.empty()){
tmp = qu.front();
qu.pop();
if(tmp->val == m) break;
tmp->Left = GetNode(2 * tmp->val);
qu.push(tmp->Left);
if(tmp->val-1 >= 0){
tmp->Right = GetNode(tmp->val - 1);
qu.push(tmp->Right);
}
}
printf("%d\n", BFS(root, m));
}

The while loop in your main() is an infinite loop. There are no conditions that will terminate that loop. Your program keeps allocating memory for the queue, until it runs out of space.
Your continue should be a break. Still, this while() loop is very inefficient, due to the exponentially-growing queue that it generates.

You need to store the level of the node (root level: 0) because this will give you the steps you need to get m.
struct Node{
int val;
Node* Left;
Node* Right;
int lev;
};
Then, getNode will have one more parameter(level):
Node* GetNode(int val,int l){
Node* newnode = new Node();
newnode->val = val;
newnode->lev = l;
newnode->Left = NULL;
newnode->Right = NULL;
return newnode;
}
The root of the tree starts with level 0:
Node* root = GetNode(n,0);
And when you want to get a new node the level will be the level of the parent +1:
node->Left = GetNode(value,(node->lev)+1);
Your break is not in the most efficient place, you should stop your loop when you add a new node (with value tmp->val*2 or tmp->val-1) and any of these are m (and dont forget to update tmp, you will use it to print the answer).
Another important thing to make your algorithm efficient is to know when does your node should be add in the tree. One of them is "if them is if tmp->val-1 is less or equal 0 (number must always be positive). Also, if the node is higher than m, then it shouldn't increase, so tmp->left is going to be created only if tmp->val < m.
Finally, if you reach a number that is already in your tree, then you should add that node (this validation is done with !nit.count(x) that means "if I dont have any x in my map").
//this if comes inmediatly after reading n and m
if (n==m){
cout<<0<<endl;
return 0;
}
while(!qu.empty()){
tmp = qu.front();
qu.pop();
if (!nit.count(2 * tmp->val) && (tmp->val<m)){
tmp->Left = GetNode(2 * tmp->val,tmp->lev+1);
//cout<<2 * tmp->val<<endl;
if ((2 * tmp->val)==m){
tmp=tmp->Left; break;
}
nit[2 * tmp->val]++;
qu.push(tmp->Left);
}
if(!nit.count(tmp->val-1) && (tmp->val-1 > 0)){
tmp->Right = GetNode(tmp->val - 1,tmp->lev+1);
//cout<<tmp->val-1<<endl;
if ((tmp->val-1)==m){
tmp=tmp->Right; break;
}
nit[tmp->val-1]++;
qu.push(tmp->Right);
}
}
Now you have the answer:
printf("%d\n",tmp->lev);
This is the entire code:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
using namespace std;
struct Node{
int val;
Node* Left;
Node* Right;
int lev;
};
Node* GetNode(int val,int l){
Node* newnode = new Node();
newnode->val = val;
newnode->lev = l;
newnode->Left = NULL;
newnode->Right = NULL;
return newnode;
}
int main(void){
int n, m;
map<int,int>nit;
scanf("%d%d", &n, &m);
if (n==m){
cout<<0<<endl;
return 0;
}
Node* root = GetNode(n,0);
nit[n++];
Node* tmp;
queue<Node*> qu;
qu.push(root);
while(!qu.empty()){
tmp = qu.front();
qu.pop();
if (!nit.count(2 * tmp->val) && (tmp->val<m)){
tmp->Left = GetNode(2 * tmp->val,tmp->lev+1);
//cout<<2 * tmp->val<<endl;
if ((2 * tmp->val)==m){
tmp=tmp->Left; break;
}
nit[2 * tmp->val]++;
qu.push(tmp->Left);
}
if(!nit.count(tmp->val-1) && (tmp->val-1 > 0)){
tmp->Right = GetNode(tmp->val - 1,tmp->lev+1);
//cout<<tmp->val-1<<endl;
if ((tmp->val-1)==m){
tmp=tmp->Right; break;
}
nit[tmp->val-1]++;
qu.push(tmp->Right);
}
}
printf("%d\n",tmp->lev);
}
Sorry for my English c:

Related

I am trying to implement a tree in c++ using class

I just wanted to implement a TreeNode class that works similar to that of a struct node for a tree implementation.
Everything is working fine except for the output that is including 0 at the beginning of the inOrder traversal. Can anyone please explain it to me why is that happening?
Input:
22,1,2,3,5,4,11,20,19,24,21
Output:
0 1 2 3 4 5 11 19 20 21 22 24
#include <bits/stdc++.h>
using namespace std;
class TreeNode{
public:
int data;
TreeNode* left;
TreeNode* right;
TreeNode(){
left = NULL;
right = NULL;
}
TreeNode(int val){
data = val;
left = NULL;
right = NULL;
}
};
void insertInorder(TreeNode* cur, int d){
if(d <= cur->data){
if(cur->left == NULL)
cur->left = new TreeNode(d);
else
insertInorder(cur->left,d);
}
else{
if(cur->right == NULL)
cur->right = new TreeNode(d);
else
insertInorder(cur->right,d);
}
}
TreeNode* makeTree(vector<int> v){
TreeNode* root = NULL;
for(int start = 0; start <= v.size(); start++){
if(start == 0){
root = new TreeNode();
root->data = v[0];
}
insertInorder(root,v[start]);
}
return root;
}
void printInorder(TreeNode* node)
{
if (node == NULL)
return;
/* first recur on left child */
printInorder(node->left);
/* then print the data of node */
cout << node->data << " ";
/* now recur on right child */
printInorder(node->right);
}
int main(){
vector<int> x = {22,1,2,3,5,4,11,20,19,24,21};
TreeNode* r = makeTree(x);
printInorder(r);
return 0;
}
Edit:
To the people visiting this questions at a future date. Better practices states that we shouldn't use
#include <bits/stdc++.h>
using namespace std;
Using namespace std can result into future namespace collisions in the code. For reference here.
I did the same mistake but I won't be doing this from now on.
Please refer to the link provided by #Jabberwocky here

recursive code for finding the height of a binary tree

I am trying to find the height of a binary tree and here is my attempt at the same
#include<iostream>
#include<stack>
using namespace std;
int total = 0;
int length = -1;
class Node{
public:
int data;
Node *left;
Node *right;
Node(int k){
data = k;
left = right = NULL;
}
};
void height(Node *root){
if(root==NULL)
return;
length++;
if(length>total)
total = length;
height(root->left);
height(root->right);
}
int main(){
Node *root = new Node(3);
root->left = new Node(4);
root->left->left = new Node(5);
root->right = new Node(6);
root->right->left = new Node(7);
height(root);
cout<<total;
return 0;
}
here length and total have been declared as global variables having values -1 and 0 respectively.
When I run the code, the output which I am getting is the number of nodes in the tree - 1 but not the height of the tree. Please let me know my mistake here.
Sure, you're incrementing length on every node.
If you're doing it recursively, it is actually very simple:
std::size_t height(Node const *root) {
if(!root) return 0;
return 1 + std::max(height(root->left), height(root->right));
}
Your approach is more of a backtracking than a simple recursion. In this approach you should be mindful to revert back to the original state at each step. Here length is always being incremented. You should revert it back.
void height(Node *root){
if(root==NULL)
return;
length++;
total = std::max(total,length+1); // Either this or initialize length as 0
height(root->left);
height(root->right);
length--; // <--- Add this line
}

Implementing a recursive Void function (Finding height of Binary Search Tree)

I need to implement a void function that computes the height of each node in a binary tree and stores it in each node. I've found a few solutions online that are recursive in nature but they return int. Examples include (https://www.geeksforgeeks.org/write-a-c-program-to-find-the-maximum-depth-or-height-of-a-tree/). The difference between the model answer, besides that it is not a void function, is that it also does not store the height in each node.
This is my attempt at the solution, but I can't seem to get the code to work, nor refit the model answer to recursively apply in a void function. When I run my code in the helper code to test, it doesn't even show any output.
void computeHeight(Node *n) {
Node* ltraverser = n;
Node* rtraverser = n;
int lheight = 0;
int rheight =0;
if (n == NULL) {
n->height = 0;
}
while (ltraverser->left != NULL) {
ltraverser = ltraverser->left;
lheight += 1;
}
while (rtraverser->right != NULL) {
rtraverser = rtraverser->right;
lheight += 1;
}
if (lheight > rheight) {
n->height = lheight;
}
else {
n->height = rheight;
}
computeHeight(n->left);
computeHeight(n->right);
}
For reference:
The starter code below defines a class called "Node" that has two child pointers ("left" , "right") and an integer "height" member variable. There is also a constructor Node() that initializes the children to nullptr and the height to -1.
/*
The height of a node is the number of edges in
its longest chain of descendants.
Implement computeHeight to compute the height
of the subtree rooted at the node n. Note that
this function does not return a value. You should
store the calculated height in that node's own
height member variable. Your function should also
do the same for EVERY node in the subtree rooted
at the current node. (This naturally lends itself
to a recursive solution!)
Assume that the following includes have already been
provided. You should not need any other includes
than these.
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
You have also the following class Node already defined.
You cannot change this class definition, so it is
shown here in a comment for your reference only:
class Node {
public:
int height; // to be set by computeHeight()
Node *left, *right;
Node() { height = -1; left = right = nullptr; }
~Node() {
delete left;
left = nullptr;
delete right;
right = nullptr;
}
};
*/
For testing the code
// This function prints the tree in a nested linear format.
void printTree(const Node *n) {
if (!n) return;
std::cout << n->height << "(";
printTree(n->left);
std::cout << ")(";
printTree(n->right);
std::cout << ")";
}
Node *n = new Node();
n->left = new Node();
n->right = new Node();
n->right->left = new Node();
n->right->right = new Node();
n->right->right->right = new Node();
computeHeight(n);
printTree(n);
std::cout << std::endl << std::endl;
printTreeVertical(n);
delete n;
n = nullptr;
return 0;
}
Instead of returning node height just recurisvely call computeHeight on left and right nodes, then store maximum height in node structure.
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>
class Node {
public:
int height;
Node *left, *right;
Node() { height = -1; left = right = nullptr; }
~Node() {
delete left;
left = nullptr;
delete right;
right = nullptr;
}
};
void computeHeight(Node *node) {
if (node == nullptr) {
return;
}
computeHeight(node->left);
computeHeight(node->right);
int leftHeight = -1;
int rightHeight = -1;
if (node->left != nullptr) {
leftHeight = node->left->height;
}
if (node->right != nullptr) {
rightHeight = node->right->height;
}
node->height = std::max(leftHeight, rightHeight) + 1;
}
void printNode(Node *n, int level = 0) {
if (n == nullptr) {
return;
}
std::cout << std::string(level * 2, ' ') << "Height = " << n->height << "\n";
printNode(n->left, level + 1);
printNode(n->right, level + 1);
}
int main() {
Node *n = new Node();
n->left = new Node();
n->right = new Node();
n->right->left = new Node();
n->right->right = new Node();
n->right->right->right = new Node();
computeHeight(n);
printNode(n);
}
Your mistake is on the following part and because of this you program exits without showing the error
if (n == NULL) {
n->height = 0;
}
When n is NULL; you should not try to access n->height. Replace it as follows and your code will work:
if (n == NULL) {
return;
}
Also, as the other answer mentioned, when you want to compute height recursively, you don't need a while loop just use the following recursive formula:
Height(n) = 1 + max(Height(n->left), Height(n->right))
Also, for consistency reasons usually the height of NULL subtree is defined to be -1. This allows the recursive formula to work properly.
Word of advice: In order to debug any program, an easy way is to just print messages before and after function calls and/or certain lines. This way by checking which messages are not printed, you can quickly pinpoint which functions/lines are causing a problem and then investigate them.

Code::Blocks: Cannot open file: ../libgcc/unwind-sjlj.c

I've been working on this project for a bit now and I'm running into this issue that I can't solve.
As a preface, the program builds a binary tree from data from a file, then the tree can grow, and the new complete information is written over that original file.
To do this all with a single information vector, I'm having my input vector be ordered in level order, however (as far as I understand, please correct me if I'm wrong), in order to do this, I need to have the NULL spaces accounted for in my vector, and to rewrite everything correctly I need faux-NULL (nodes that fill space but don't contain any actual information other than pointers) nodes on my tree.
When the tree grows, then, I'm trying to complete and balance it with "NULL" nodes, and I do so recursively with an in-order traversal and the depth in mind. When I run this, however, I'm getting a Segmentation Fault, and when I run it step by step with the debugger, I'm getting
Cannot open file: ../../../../../src/gcc-4.9.2/libgcc/unwind-sjlj.c
specifically. It occurs when, during the recursive traversal, the algorithm adds a node, and upon reaching the "return" portion of the node's memory allocator, the error pops up and the program breaks.
Is this an error with my code or is it an error with Code::Blocks' libraries?
Relevant code:
struct Node
{
int idx; //idx is information relevant to the program but not to the structure
std::string phrase;
Node* left, * right;
};
Node* newNode(std::string data, int idx) //memory allocator
{
Node* node = new Node;
node->phrase = data;
node->idx = idx;
node->left = node->right = NULL;
return (node); //right here is where the debugger gives me the error
}
// Function to insert nodes in level order
Node* insertLevelOrder(std::string arr[], int idx[], Node* root,int i, int n)
{
// Base case for recursion
if (i < n)
{
Node* temp = newNode(arr[i],idx[i]);
root = temp;
// insert left child
root->left = insertLevelOrder(arr,idx,root->left, 2 * i + 1, n);
// insert right child
root->right = insertLevelOrder(arr,idx,root->right, 2 * i + 2, n);
}
return root;
}
int calcularProfundidad(Node * root) //Sorry for the spanglish--this is "calculateDepth"
{
if (root == NULL)
{
return 0;
}
int h1 = calcularProfundidad(root->left); //recursively calculate depth of left subtree
int h2 = calcularProfundidad(root->right); //and of right subtree
return 1 + max(h1,h2);
}
void rellenarNulos(Node * root, int prof, int counter) //fills "empty spaces" with "faux-NULL" nodes
{
if(counter == prof) //if reaches depth, stops, if not, adds more nodes
return;
if(root->left == NULL && counter < prof)
{
Node * auxNode = newNode("NULL",0); //error in this call
root->left = auxNode;
}
if(root->right == NULL && counter < prof)
{
Node * auxNode2 = newNode("NULL",0);
root->right = auxNode2;
}
rellenarNulos(root->left,prof,counter++);
rellenarNulos(root->right,prof,counter++);
}
#include <iostream>
#include <fstream>
#include <string>
#include "arbLib.hpp"
using namespace std;
int main()
{
//Builds tree from file
int N;
fstream myfile ("test.txt");
if (!myfile.is_open())
{
cout << "Unable to open file" << endl;
return 0;
}
myfile >> N; //N is the number of nodes
string words[N];
for(int i=0;i<N;i++)
myfile >> words[i];
int nums[N];
for(int j=0;j<N;j++)
myfile >> nums[j];
myfile.close();
//Builds tree from these vectors that are level order
Node *root = insertLevelOrder(words,nums,root,0,N);
int prof = calcularProfundidad(root); //calculates depth
rellenarNulos(root,prof,1); //here is where the program dies
inOrder(root);
destroyTree(root);
cout << endl;
return 0;
}

finding smallest two nodes in a linked list in c

I am trying to find the smallest two numbers in a linked list in C++ (without using any built-in functions).
I tried to do so as below:
My logic is:
(1) Assume the first node in the linked list is minimum1 and the second is minimum2. Compare them. The greater becomes minimum2 and the smaller becomes minimum1.
(2) Start from the third node (third because we have already covered first and second) in a while loop until we reach NULL, thus traversing all the list.
(3) Compare the newly traversed node with minimum1 and minimum2. If this node is smaller than minimum1, then put its value in minimum1. minimum2 now will contain the value of minimum1, and minimum1 will contain the value of the newly found node which was smaller than minumum1.
Below is my code which takes the number of nodes to be created, reads the values of all nodes continuously (just keep on pressing Enter after every number), and creates the linked list from all the nodes. These are working fine.
Code
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node* next;
};
typedef struct node node;
node* tree;
// Finding minimum two elements:
void find_two_min(node** List, node** lmin1, node** lmin2)
{
int i;
node* temp = *List;
node *min1, *min2;
node* var1 = *List;
node* second = (*List)->next;
if (var1 > second)
{
min2 = var1;
min1 = second;
}
else
{
min1 = var1;
min2 = second;
}
while (temp->next->next->next != NULL)
{
if (temp->freq < min2->freq)
{
min1 = min2;
min2 = temp;
}
else if (temp->freq < min1->freq)
{
min1 = temp;
}
temp = temp->next;
}
*lmin1 = min1;
*lmin2 = min2;
}
void main()
{
int size, data;
node *min1, *min2;
int count = 0; // This flag is to check whether it's the first node inside the do-while loop.
tree = NULL;
printf("Enter the number of nodes:\n");
scanf("%d", &size);
printf("Enter the elements:\n");
node* prev;
do
{
scanf("%d", &data);
if (count == 0)
{
node* temp;
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev = temp;
tree = prev;
}
else
{
node* temp;
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev->next = temp;
prev = prev->next;
}
--size;
++count;
}
while (size > 0);
printf("Printing linked list:\n");
node* temp1;
temp1 = tree;
while (temp1 != NULL)
{
printf("%d, ", temp1->freq);
temp1 = temp1->next;
}
node* temp5 = tree;
find_two_min(&temp5, &min1, &min2);
printf("\nThe two minimum numbers are min1: %d and min2: %d.\n", min1->freq, min2->freq);
}
My code doesn't work on the following input (it gives the wrong output):
Enter the number of nodes:
4
Enter the elements:
0
-5
-2
8
Printing linked list:
0, -5, -2, 8,
The two minimum numbers are min1: 0 and min2: -5.
It was supposed to print "min1: -5" and "min2: -2" but I don't know why it doesn't.
Could anyone please help me eliminate this problem? Any algorithm or piece of code in C/C++ to use as a reference is appreciated. Thanks.
Note: I can't use any built-in functions.
If trying to do 2 things at once confuses you,
then do only 1 thing,
AND LATER, follow that with another singular effort.
i.e.
1st - write search1() to find the smallest item and record the node pointer.
2nd - write search2() to find the smallest item, but add to your search2 the idea to compare the node address to the previously found smallest node. And when already found, skip it as if was not even there.
Implement search1, debug it, and get that working.
AFTER THAT
Implement search2, (probably a copy) and pass in the node pointer found in the search1.
Each time you find a possible update to the search2's smallest node,
insert a test to determine if this node matches the previously found
You have a bug in the line
if(var1>second)
This is comparing the memory addresses of the two nodes, not their frequencies!
There's another bug in the line
if(temp->freq<min2->freq)
and the later line
else if(temp->freq<min1->freq)
The code inside the if statement block following the first line behaves as though you compared temp->freq with min1->freq, not min2->freq as you're currently doing -- and vice versa for the code inside the else if statement block following the second line.
Have two ints min1, min2, both INT_MAX (from limits.h). (Assumption: No element can have the value INT_MAX.)
Walk through your list, one by one. For each element do:
If it is smaller than min1 then min1 is now the second smallest ever, so assign min1 to min2. Then replace min1 with the element.
If it is not smaller than min1 but smaller than min2, it replaces min2.
If none of the above, skip element.
After iterating the list min1 will hold the smallest list value, min2 the second smallest. If min2 is INT_MAX, the list had only one element. If min1 is INT_MAX, the list was empty.
I don't have a full answer for you, but I don't trust checking temp->next->next->next!=NULL in a while loop. That's going to have problems with short lists.
You might be better off looking at one item at a time. Set your two min values to maximum possible value (i.e. INT_MAX) and the node pointers to NULL.
If the value of the first item on the list is less than one of your two min values, update the min value and node pointer.
If the value of the next item on the list is less than one of your two min values, update the min value and the node pointer. You may need to rearrange the order of the min values.
Repeat until you've looked at every item in the list.
You should have your answer when you get to the end of the list and the pointer manipulation will be easier to trace/debug.
I have done the solution of my question using INT_MAX. It works fine:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <limits.h>
struct node
{
int freq;
struct node * next;
};
typedef struct node node;
node * tree;
//Problem creating area is below (code for finding minimum two elements)
void find_two_min(node * * List, node * * lmin1, node * * lmin2)
{
node * temp = * List;
node * min1;
min1 = (node*) malloc(sizeof(node));
min1 -> freq = INT_MAX;
node * min2;
min2 = (node*) malloc(sizeof(node));
min2 -> freq = INT_MAX; //This initialisation of INT_MAX to min2->freq creates problem because printf() statment above it works well but don't work below it.
printf("check1\n");
while (temp != NULL)
{
printf("\ncheck2\n");
if ((temp) -> freq < min2 -> freq)
{
printf("check3\n");
min1 = min2;
min2 = temp;
}
else if ((temp) -> freq < min1 -> freq && (temp) -> freq != min2 -> freq)
{
printf("check4\n");
min1 = temp;
}
temp = temp -> next;
}
* lmin1 = min1;
* lmin2 = min2;
printf("address of min2 is : %d and value is %d \n" ,min2, min2->freq);
printf("check5\n");
}
//Problem creating area is above//
void main()
{
int size, data;
node * min1;
node * min2;
int count = 0; //this count flag is to check is it's first node or not inside the do-while loop.
tree = NULL;
printf("enter the size of node\n");
scanf("%d", & size);
printf("start entering the number of elements until your size\n");
node * prev;
do {
scanf("%d", & data);
if (count == 0)
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp -> freq = data;
temp -> next = NULL;
prev = temp;
tree = prev;
}
else
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp -> freq = data;
temp -> next = NULL;
prev -> next = temp;
prev = prev -> next;
}
size--;
++count;
}
while (size > 0);
printf("Printing linked list\n");
node * temp1;
temp1 = tree;
while (temp1 != NULL)
{
printf("%d-> ", temp1 -> freq);
temp1 = temp1 -> next;
}
node * temp5 = tree;
find_two_min( & temp5, & min1, & min2);
printf("\n The two minimum numbers are min1 :%d and min2 : %d\n", min1 -> freq, min2 -> freq);
}
This should do it:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node {
int freq;
struct node* next;
};
typedef struct node node;
//Function Prototype
void find_two_min(node**, node**, node**);
void main() {
node* min1 = (node*) malloc(sizeof(node));
node* min2 = (node*) malloc(sizeof(node));
node* tree = NULL;
node* prev;
node* temp1;
node* temp;
node* temp5 = tree;
int size, data;
int count = 0; //this count flag is to check is it's first node or not inside the do-while loop.
printf("enter the size of node\n");
scanf("%d", &size);
printf("start entering the number of elements until your size\n");
do {
scanf("%d", & data);
if (count == 0) {
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev = temp;
tree = prev;
} else {
node* temp;
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev->next = temp;
prev = prev->next;
}
size--;
++count;
} while (size > 0);
printf("Printing linked list\n");
temp1 = tree;
while (temp1) {
printf("%d-> ", temp1->freq);
temp1 = temp1->next;
}
if (count > 1) {
find_two_min(&tree, &min1, &min2);
printf("\n The two minimumnumbers are min1 :%d and min2 : %d\n",min1->freq,min2->freq);
} else
printf("\n Not enough data\n\n");
}
//Function Definition
void find_two_min(node** List,node** lmin1,node** lmin2) {
node* temp = *List;
node* min1;
node* min2;
node* var1 = *List;
node* second=(*List)->next;
/* OLD ONE
if (var1->freq > second->freq) {
min2 = var1;
min1 = second;
} else {
min1 = var1;
min2 = second;
}
*/
if (var1->freq > second->freq) {
min1 = var1;
min2 = second;
} else {
min2 = var1;
min1 = second;
}
while(temp->next) {
printf("\nCurrent freq is %d", temp->freq);
printf("\nNext freq is %d", (temp->next)->freq);
if ((temp->next)->freq < min2->freq) {
printf("\n Condition one is fulfilled");
min1 = min2;
min2 = temp->next;
} else if ((temp->next)->freq < min1->freq) {
printf("\n Condition two is fulfilled");
min1 = temp->next;
}
temp = temp->next;
}
*lmin1 = min1;
*lmin2 = min2;
}