convert an ordered linked list to binary search tree - c

Here's my code. Please let me know the bug.The question is to convert a given ordered linked list into a binary search tree.
Thanks.
struct treenode* makeBSTnode(struct node* head)
{
struct treenode *root=(struct treenode*)malloc(sizeof(struct treenode));
root->data = head->data;
root->leftchild = NULL;
root->rightchild = NULL;
return root;
}
struct treenode* makeBST(struct node **head,int iterations)
{
if(iterations==0)
{
/*this is the code for the base condition*/
struct treenode *root=(struct treenode*)malloc(sizeof(struct treenode));
root = makeBSTnode(*head);
return root;
}
else
{
/*this is for the case when the node is not single but should be broken down into parts*/
struct node *leftchildnode=NULL,*rightchildnode=NULL,*rootnode=NULL,*temp;
temp = (struct node*)malloc(sizeof(struct node));
struct treenode *root = (struct treenode*)malloc(sizeof(struct treenode));
int limit = (int)ceil((float)(3*iterations)/2);
for(int i=1;i<=limit;i++)
{
if(i==(int)ceil((float)iterations/2))
{
leftchildnode = (struct node*)malloc(sizeof(struct node));
leftchildnode = *head;
}
else if(i==iterations)
{
rootnode = (struct node*)malloc(sizeof(struct node));
rootnode = *head;
}
else if(i==(int)ceil((float)(3*iterations)/2))
{
rightchildnode = (struct node*)malloc(sizeof(struct node));
rightchildnode = *head;
}
if(*head)
(*head) = (*head)->next;
else
break;
}
root = makeBSTnode(rootnode);
root->leftchild = makeBST(&temp,(int)ceil((float)iterations/2));
root->rightchild = makeBST(&rootnode,(int)ceil((float)(3*iterations/2)));
return root;
}
}
I called this makeBST function in main as:
root = makeBST(&head,(int)ceil((float)length/2));

Related

How to use the variable globally in the function

I am writing a C code to insert an element to a sorted linked list. In this code I am using the variable "place" for deciding the position to insert the new element. But here it is getting error that "place" variable is to declared first. But I need the place globally for using in other functions. So what can I do to make it work? Also there is some problem with the function calling in the last part of main function. Please help me to correct it. Please let me know if there are any other errors. Thank You
#include<stdio.h>
#include<stdlib.h>
struct Node{
int data;
struct Node *next;
};
int calcSize(struct Node* node){
int size=0;
while(node!=NULL){
node = node->next;
size++;
}
return size;
}
void insertPosition(int pos, int data, struct Node** head)
{
int size = calcSize(*head);
if(pos < 1 || size < pos)
{
printf("Can't insert, %d is not a valid position\n",pos);
}
else
{
struct Node* temp = *head;
struct Node* newNode = (struct Node*)
malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
while(--pos)
{
temp=temp->next;
}
newNode->next= temp->next;
temp->next = newNode;
}
}
void insertStart(struct Node** head, int data){
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = *head;
*head = newNode;
}
void insertLast(struct Node** head, int data){
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
if(*head==NULL){
*head = newNode;
return;
}
struct Node* temp = *head;
while(temp->next!=NULL)
temp = temp->next;
temp->next = newNode;
}
void display(struct Node* node){
while(node!=NULL){
printf("%d ",node->data);
node = node->next;
}
printf("\n");
}
void check(struct Node* node,int ele){
while(node!=NULL){
int i=0;
if(ele>node->data)
{ place=i; break;}
node= node->next;
}
}
int main()
{ int ele; int place=0;
struct Node* head = NULL;
struct Node* node2 = NULL;
struct Node* node3 = NULL;
struct Node* node4 = NULL;
struct Node* node5 = NULL;
head = (struct Node*)malloc(sizeof(struct Node));
node2 = (struct Node*)malloc(sizeof(struct Node));
node3 = (struct Node*)malloc(sizeof(struct Node));
node4 = (struct Node*)malloc(sizeof(struct Node));
node5 = (struct Node*)malloc(sizeof(struct Node));
head->data = 5; head->next = node2;
node2->data = 10; node2->next = node3;
node3->data = 18; node3->next = node4;
node4->data = 26; node4->next = node5;
node5->data = 32; node5->next = NULL;
printf("Current Items in Linked List\n");
display(head);
printf("Enter the element to insert into LL\n");
scanf("%d",&ele);
printf("Inserting into Linked List....");
if(place=1)
{ void insertStart(&head, ele); }
else if(place=5)
{ void insertLast(&head, ele); }
else
{ void insertPosition(place, ele, &head); }
return 0;
}

Turbo C gives a totally different output than GCC, although the same code

So, here I wanted to add 2 polynomials using a linked-list in C. It gave a perfect output when compiled with GCC, but when compiled with TurboC++, it messed up...
The output it gave in GCC was:
Polynomial 1: 6x^3 + 10x^2 + 0x + 5
Polynomial 2: 4x^2 + 2x + 1
Added Polynomial : 6x^3 + 14x^2 + 2x + 6
The Output it gave in TurboC++:
Polynomial 1: 6x^3 + <br>
Polynomial 2: 4x^2 <br>
Added Polynomial : 6x^3 + 4x
Here is the code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct node {
int coeff;
int power;
struct node *next;
};
void display_poly(struct node *exp);
void addnode(int coeff, int power, struct node **prev_node);
void addpoly(struct node *poly1, struct node *poly2, struct node *result);
void main() {
struct node *poly1 = NULL, *poly2 = NULL, *result = NULL;
addnode(6, 3, &poly1);
addnode(10, 2, &poly1);
addnode(0, 1, &poly1);
addnode(5, 0, &poly1);
printf("\nPolynomial 1:\t");
display_poly(poly1);
addnode(4, 2, &poly2);
addnode(2, 1, &poly2);
addnode(1, 0, &poly2);
printf("\nPolynomial 2:\t");
display_poly(poly2);
result = (struct node *)malloc(sizeof(struct node));
addpoly(poly1, poly2, result);
printf("\nAdded Polynomial :\t");
display_poly(result);
return;
}
void addnode(int coeff, int power, struct node **prev_node) {
struct node *node1, *node2;
node2 = *prev_node;
if (node2 == NULL) {
node1 = (struct node *)malloc(sizeof(struct node));
node1->coeff = coeff;
node1->power = power;
*prev_node = node1;
node1->next = (struct node *)malloc(sizeof(struct node));
node1 = node1->next;
node1->next = NULL;
} else {
node1->coeff = coeff;
node1->power = power;
node1->next = (struct node *)malloc(sizeof(struct node));
node1 = node1->next;
node1->next = NULL;
}
return;
}
void display_poly(struct node *exp) {
while (exp->next) {
if (exp->power == 0) {
printf("%d", exp->coeff);
} else if (exp->power == 1) {
printf("%dx", exp->coeff);
} else {
printf("%dx^%d", exp->coeff, exp->power);
}
exp = exp->next;
if (exp->coeff >= 0 && exp->next != NULL) {
printf(" + ");
} else {
printf(" ");
}
}
return;
}
void addpoly(struct node *poly1, struct node *poly2, struct node *result){
while (poly1->next && poly2->next) {
if (poly1->power > poly2->power) {
result->power = poly1->power;
result->coeff = poly1->coeff;
poly1 = poly1->next;
} else if (poly2->power > poly1->power) {
result->power = poly2->power;
result->coeff = poly2->coeff;
poly2 = poly2->next;
} else {
result->power = poly1->power;
result->coeff = poly1->coeff + poly2->coeff;
poly1 = poly1->next;
poly2 = poly2->next;
}
result->next = (struct node *)malloc(sizeof(struct node));
result = result->next;
result->next = NULL;
}
while (poly1->next || poly2->next) {
if (poly1->next) {
result->power = poly1->power;
result->coeff = poly1->coeff;
poly1 = poly1->next;
}
if (poly2->next) {
result->power = poly2->power;
result->coeff = poly2->coeff;
poly2 = poly2 -> next;
}
result->next = (struct node *)malloc(sizeof(struct node));
result = result->next;
result->next = NULL;
}
}
Your code has undefined behaviour:
void addnode(int coeff, int power, struct node** prev_node)
{
struct node* node1, * node2; // <<< node1 is not initialized
node2 = *prev_node;
if (node2 == NULL) {
node1 = (struct node*)malloc(sizeof(struct node));
node1->coeff = coeff;
node1->power = power;
*prev_node = node1;
node1->next = (struct node*)malloc(sizeof(struct node));
node1 = node1->next;
node1->next = NULL;
}
else {
node1->coeff = coeff; // <<<< here node1 is not initialized
node1->power = power;
node1->next = (struct node*)malloc(sizeof(struct node));
node1 = node1->next;
node1->next = NULL;
}
return;
}
node1 has not been initialized (see comment in the code above), and dereferencing an uninitialized pointer is undefined behaviour (google that term). Change struct node* node1 to struct node* node1 = NULL and run the program again. This time you'll most likely get a segfault with gcc. With Turbo C I don't know what is going to happen.
You probably want this:
void addnode(int coeff, int power, struct node** prev_node) {
struct node* node1 = NULL , *node2;
node2 = *prev_node;
node1 = malloc(sizeof(struct node));
node1->coeff = coeff;
node1->power = power;
node1->next = malloc(sizeof(struct node));
if (node2 == NULL) {
*prev_node = node1;
node1 = node1->next;
node1->next = NULL;
}
else {
node1 = node1->next;
node1->next = NULL;
}
return;
}
BTW: the (struct node*) of malloc are useless, you can simply drop them.
That being said, don't use Turbo C, this is an antiquated piece of software that is most likely older than you.
There may be other problems in your code though.

How to make to linked list in C?

Using two linked lists or something similar, I want to add "ABCD", then I want to get "ABDC".
I'm not sure if my code is right, I'm a noob in C.
The code should have pointer and malloc. I made it like this:
struct Node
{
char data;
struct Node* next;
};
struct Node* newNode(char data)
{
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->next = NULL;
return node;
}
struct Node* constructList()
{
struct Node* first = newNode(1);
struct Node* second = newNode(2);
struct Node* third = newNode(3);
struct Node* forth = newNode(4);
struct Node* head = first;
first->next = second;
second->next = third;
third->next=forth;
return head;
}
void printList(struct Node* head)
{
struct Node* ptr = head;
while (ptr)
{
printf("%d -> ", ptr->data);
ptr = ptr->next;
}
printf("NULL");
}
Your code is fine as shown, though it lacks error handling (and why are you using char to store integers?).
Do make sure you free() the nodes when you are done using them, eg:
void freeList(struct Node* head)
{
struct Node* ptr = head;
struct Node* next;
while (ptr)
{
next = ptr->next;
free(ptr);
ptr = next;
}
}
I would suggest changing constructList() to use a loop, eg:
struct Node* constructList()
{
struct Node *head = NULL;
struct Node **ptr = &head;
for (int value = 1; value <= 4; ++value)
{
*ptr = newNode(value);
if (*ptr == NULL)
{
freeList(head);
return NULL;
}
ptr = &((*ptr)->next);
}
return head;
}
You could then generalize constructList() to take an array of integers, or a string, as input and loop through that input adding a new node for each value. For example, try this:
struct Node
{
char data;
struct Node* next;
};
struct Node* newNode(char data)
{
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
if (node)
{
node->data = data;
node->next = NULL;
}
return node;
}
void freeList(struct Node* head)
{
struct Node* ptr = head;
struct Node* next;
while (ptr)
{
next = ptr->next;
free(ptr);
ptr = next;
}
}
struct Node* constructList(const char *str)
{
struct Node *head = NULL;
struct Node **ptr = &head;
char ch;
if (str)
{
while ((ch = *str++) != '\0')
{
*ptr = newNode(ch);
if (*ptr == NULL)
{
freeList(head);
return NULL;
}
ptr = &((*ptr)->next);
}
}
return head;
}
void printList(struct Node* head)
{
struct Node* ptr = head;
while (ptr)
{
printf("%c -> ", ptr->data);
ptr = ptr->next;
}
printf("NULL");
}
struct Node *list = constructList("ABCD");
printList(list);
freeList(list);

Why can't I set list pointer to minimal value (sorting words) in the list?

After inserting new element to the circular doubly linked list, when I set list pointer to minimal value, I can't see the value which was inserted to the list first (by creating the list), I can see only strange characters.
if I don't set the pointer to minimal value everything is working correctly, but I care to have the pointer set to minimal value.
struct Person {
char surname[N];
};
struct c_dll {
struct Person *data;
struct c_dll *next, *prev;
};
struct c_dll *create_list(char *surname) {
struct Person *new_person = (struct Person *)malloc(sizeof(struct Person));
strcpy(new_person->surname, surname);
struct c_dll *new_node = (struct c_dll *)malloc(sizeof(struct c_dll));
if (new_node != NULL) {
new_node->data = new_person;
new_node->next = new_node->prev = new_node;
}
return new_node;
};
struct c_dll *find_min(struct c_dll *node) {
char min_surname[20];
struct c_dll *result, *start;
strcpy(min_surname, node->data->surname);
start = result = node;
do {
if (strcmp(min_surname, node->data->surname) > 0) {
strcpy(min_surname, node->data->surname);
result = node;
}
node = node->next;
} while (start != node);
return result;
}
struct c_dll *find_next_node(struct c_dll *node, char *surname) {
node = find_min(node);
struct c_dll *start = node;
do {
if (strcmp(node->data->surname, surname) > 0)
break;
node = node->next;
} while (start != node);
return node;
}
void add_element(struct c_dll **list_ptr, char *surname) {
struct Person *new_person = (struct Person *)malloc(sizeof(struct Person));
strcpy(new_person->surname, surname);
struct c_dll *new_node = (struct c_dll *)malloc(sizeof(struct c_dll));
if (new_node != NULL) {
struct c_dll *node;
new_node->data = new_person;
node = find_next_node(&(*list_ptr), surname);
new_node->next = node;
new_node->prev = node->prev;
node->prev->next = new_node;
node->prev = new_node;
}
(*list_ptr) = find_min(&(*list_ptr));
}
The bug is in add_element: you pass &(*list_ptr) to find_min and find_next_node, which is incorrect and even a type mismatch that the compiler should diagnose.
You should just pass *list_ptr instead.
Here is a modified version:
int add_element(struct c_dll **list_ptr, const char *surname) {
struct Person *new_person = malloc(sizeof(*new_person));
if (new_person == NULL)
return -1;
strcpy(new_person->surname, surname);
struct c_dll *new_node = malloc(sizeof(*new_node));
if (new_node == NULL) {
free(new_person);
return -1;
} else {
struct c_dll *node;
new_node->data = new_person;
node = find_next_node(*list_ptr, surname);
new_node->next = node;
new_node->prev = node->prev;
node->prev->next = new_node;
node->prev = new_node;
*list_ptr = find_min(*list_ptr);
return 0;
}
}

insert end linked list

I am having problem in inserting data at the end of the linked list. I have tried everything but no help. It is only showing first and the last no but the numbers in between.
Following is my code.
struct node
{
int data;
struct node *next;
} *start;
add()
{
int a,b,c=0;
scanf("%d",&a);
struct node *new,*new1;
new=(struct node *)malloc(sizeof(struct node));
new1=(struct node *)malloc(sizeof(struct node));
while(a!=0)
{
c=a%10;
a=a/10;
if(start==NULL)
{
new->data=c;
start=new;
printf("%d\n",start->data);
}
else
{
new1->data=c;
new->next=new1;
new=new->next;
}
}
new->next=NULL;
}
you are re-writing 2nd node every-time. move to the last of linked list and then add
add()
{
int a,b,c=0;
scanf("%d",&a);
struct node *new,*new1;
while(a!=0)
{
c=a%10;
a=a/10;
new=(struct node *)malloc(sizeof(struct node));
if(start==NULL)
{
new->data=c;
new->next = NULL;
start=new;
printf("%d\n",new->data);
}
else
{
new1=(struct node *)malloc(sizeof(struct node));
new1 = start;
while(new1->next != NULL) {
new1 = new1->next;
}
new->data=c;
new->next = NULL;
printf("%d\n",new->data);
}
}
}
void print(struct node *p){
while(p){
printf("%d\n", p->data);
p = p->next;
}
}
void add(void){
int a;
scanf("%d", &a);
struct node *new, *curr;
for( ;a!=0; a /= 10){
new = (struct node *)malloc(sizeof(struct node));
new->data = a % 10;
new->next = NULL;
if(start==NULL)
start = curr = new;
else
curr = curr->next = new;
}
print(start);
}
Solved it. The problem was that I was using the same new1 again and again. When the satisfying case appears it should be always allocated memory. The modified code is as below:-
int a,b,c=0;
scanf("%d",&a);
while(a!=0)
{
struct node *new,*new1;
c=a%10;
a=a/10;
if(start==NULL)
{
new=(struct node *)malloc(sizeof(struct node));
new->data=c;
start=new;
printf("%d\n",start->data);
}
else
{
new1=(struct node *)malloc(sizeof(struct node));
new1->data=c;
new->next=new1;
printf("%d\n",new->next->data);
new=new->next;
new->next=NULL;
}
}

Resources