I created a linked list and then used the following search function to get the position of the data field,but it returns the value as the last element of the linked list.I am unable to guess why
int search(struct node *curr,int d,int i)
{
if (!(curr-1))
return(0);
if (curr->data == d)
return i;
else
{
i++;
search(curr->link,d,i);
}
}
I used the following statement to control it from main:
m=search(first,data,i) //here first is the pointer to first element to first element and data is element to search
if (!(curr-1))
Why -1?
else
{
i++;
search(curr->link,d,i);
}
You have forgotten the return statement. Otherwise, the return value is undefined. Then, your recursive search function might look like:
int search(struct node *curr, int d, int i)
{
if (curr == NULL)
return 0; /* If 1 <= i <= n */
else if (curr->data == d)
return i;
else
return search(curr->link, d, i + 1);
}
Why recursion? You learn bad habits.
int search(struct node* curr, int d, int i)
{
if (NULL == curr)
{
return 0;
}
i = 1;
while(curr->data != d)
{
if (NULL != curr->link)
{
curr = curr->link;
++i;
}
else
{
return 0;
}
}
return i;
}
Related
I was trying to figure out a code about heap sort using binary tree that I saw on stackoverflow.com,
here is the code:
//Heap Sort using Linked List
//This is the raw one
//This getRoot function will replace the root with number in the last node, after the main prints the largest number in the heap
//The heapSort function will reconstruct the heap
//addNode function is as same as in binary search tree
//Note addNode and heapSort are recursive functions
//You may wonder about the for loop used in main, this actually tells the depth of the tree (i.e log base2 N)
//With this value these functions find where to trverse whether left or right(direction), with help of macro GETBIT (0-left,1-right)
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define GETBIT(num,pos) (num >> pos & 1)
struct node
{
int data;
struct node *left;
struct node *right;
};
typedef struct node node;
int nodes;
node *first, *tmp, *current;
void addNode(node *,node *,int);
void swap(int *, int *);
void getRoot(node *, int);
void heapSort(node *);
int main()
{
int num;
int cont,i,j;
while(1) //It gets number from user if previous value is non zero number
{
printf("Enter a number\n");
scanf("%d",&num);
if(!num) //i'm using 0 as terminating condition to stop adding nodes
break; //edit this as you wish
current = (node *)malloc(sizeof(node));
if(current == 0)
return 0;
current->data = num;
nodes++;
for(i=nodes,j=-1; i; i >>= 1,j++);
if(first == 0)
{
first = current;
first->left = 0;
first->right = 0;
}
else
addNode(first,first,j-1);
printf("Need to add more\n");
}
printf("Number of nodes added : %d\n",nodes);
while(nodes)
{
printf(" %d -> ",first->data); //prints the largest number in the heap
for(i=nodes,j=-1; i; i >>= 1,j++); //Updating the height of the tree
getRoot(first,j-1);
nodes--;
heapSort(first);
}
printf("\n\n");
return 0;
}
void swap(int *a,int *b)
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
void addNode(node *tmp1,node *parent, int pos)
{
int dirxn = GETBIT(nodes,pos); // 0 - go left, 1 - go right
if(!pos)
{
if(dirxn)
tmp1->right = current;
else
tmp1->left = current;
current->left = 0;
current->right = 0;
if(current->data > tmp1->data)
swap(¤t->data, &tmp1->data);
}
else
if(dirxn)
addNode(tmp1->right,tmp1,pos-1);
else
addNode(tmp1->left,tmp1,pos-1);
if(tmp1->data > parent->data)
swap(&parent->data,&tmp1->data);
}
void getRoot(node *tmp,int pos)
{
int dirxn;
if(nodes == 1)
return ;
while(pos)
{
dirxn = GETBIT(nodes,pos);
if(dirxn)
tmp = tmp->right;
else
tmp = tmp->left;
pos--;
}
dirxn = GETBIT(nodes,pos);
if(dirxn)
{
first->data = tmp->right->data;
free(tmp->right);
tmp->right = 0;
}
else
{
first->data = tmp->left->data;
free(tmp->left);
tmp->left = 0;
}
}
void heapSort(node *tmp)
{
if(!tmp->right && !tmp->left)
return;
if(!tmp->right)
{
if(tmp->left->data > tmp->data)
swap(&tmp->left->data, &tmp->data);
}
else
{
if(tmp->right->data > tmp->left->data)
{
if(tmp->right->data > tmp->data)
{
swap(&tmp->right->data, &tmp->data);
heapSort(tmp->right);
}
}
else
{
if(tmp->left->data > tmp->data)
{
swap(&tmp->left->data, &tmp->data);
heapSort(tmp->left);
}
}
}
}
I don't really understand the right shift operator
so I tried to replace for(i=nodes,j=-1; i; i >>= 1,j++);
with
int o, j=0;
for(int i=1;;i=pow(2, j)){
if(nodes<i){
o = j-1;
break;
}
j+=1;
}
but I don't understand dirxn = GETBIT(nodes,pos);
my question is what does this do?
and can anyone tell me what should I do to replace this with something without a shift operator?
any help will be greatly appreciated
So i've got this problem where I'm supposed to find the level of an element in a tree. Nothing seems to work out so im reaching out here for help.
This is what i've got so far. The problem here is that the 4th assert, where the returned level is supposed to be 2, doesnt work and the assert is alerted. I've thought of maybe trying to not do it recursivly, but how could that be done?
int findElementLevel(const BSTree tree, const int element) {
int level = 0;
if (tree == NULL) {
return -1;
}
if (tree->data == element) {
return level;
}
if (element < (tree)->data) {
level++;
findElementLevel(tree->left, element);
return level;
}
if (element > (tree)->data) {
level++;
findElementLevel(tree->right, element);
return level;
}
}
void testNewTree(void) {
BSTree tree = emptyTree();
assert(isEmpty(tree));
int arr[5] = {3,2,5,1,4}, i;
for (i = 0; i < 5; i++)
{
insertSorted(&tree, arr[i]);
}
assert(findElementLevel(tree, 3) == 0);
assert(findElementLevel(tree, 2) == 1);
assert(findElementLevel(tree, 5) == 1);
assert(findElementLevel(tree, 1) == 2);
assert(findElementLevel(tree, 4) == 2);
}
The function always starts from the declaration of the local variable level that is set to 0.
int findElementLevel(const BSTree tree, const int element) {
int level = 0;
This value that is 0 (or 1 due to its increment in a current recursive function call) )is returned in case when the target element is found in any actual level
if (tree->data == element) {
return level;
}
You have to accumulate levels.
A recursive function can be defined for example the following way
int findElementLevel(const BSTree tree, const int element) {
if (tree == NULL) {
return -1;
}
else if ( element < tree->data ) {
int level = findElementLevel(tree->left, element);
return level == -1 ? level : level + 1;
}
else if ( tree->data < element ) {
int level = findElementLevel(tree->right, element);
return level == -1 ? level : level + 1;
}
else {
return 0;
}
}
Pay attention to that the qualifier const for the second parameter does not make great sense because the function deals with a copy of the value of the supplied argument. The function can be declared just like
int findElementLevel(const BSTree tree, int element);
This function is easier and shorter to write iteratively than recursively. The code is just:
int findElementLevel(const BSTree tree, const int element)
{
for (int level = 0; tree; ++level)
{
if (tree->data == element)
return level;
tree = tree->data < element ? tree->left : tree->right;
}
return -1;
}
With explanation, it is:
int findElementLevel(const BSTree tree, const int element)
{
/* Use a loop to process each level. We start counting levels at zero and
increment on each iteration. We continue as long as there is more of
the tree to explore ("tree" evaluates as true, i.e., non-null), or jump
out of the loop with a return if the target element is found.
*/
for (int level = 0; tree; ++level)
{
// If we found the target, return the level it is on.
if (tree->data == element)
return level;
/* Otherwise, descend to the left or the right according to which
side the target element must be on.
*/
tree = tree->data < element ? tree->left : tree->right;
}
/* If we reached the end of the tree without finding the element, return
-1.
*/
return -1;
}
I am having trouble getting the element from the binary tree at a specific index. The function that i am having trouble with is generic tree_get_at_index(tree_node* t, int index) {
The assignment asks me to find the element at a particular index in a binary tree. For example the 0 index should return the lowest element in the binary tree and the index = treesize should return the largest element in the tree. i have a size function in my tree which works correctly but i cannot get the indexing to work for some reason. any help would be appreciated. thank you
Right now i am getting seg fault after the tree runs once.
#include "tree.h"
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
/* Memory Management */
/* This constructor returns a pointer to a new tree node that contains the
* given element.*/
tree_node* new_tree_node(generic e) {
/*TODO: Complete this function!*/
tree_node* to_return = malloc(sizeof(tree_node));
to_return->element = e;
to_return->left = NULL;
to_return->right = NULL;
return to_return;
}
/* This function is expected to free the memory associated with a node and all
* of its descendants.*/
void free_tree(tree_node* t) {
/*TODO: Complete this function!*/
if (t != NULL){
free_tree(t->left);
free_tree(t->right);
free(t);
}
}
/* End Memory Management */
/* Tree Storage and Access */
bool tree_contains(tree_node* t, generic e) {
/*TODO: Complete this function!*/
/*
if (t == NULL || t->element != e) {
return false;
}
else if (t->element == e) {
return true;
}
return tree_contains(t,e);
}
*/
if(t == NULL )
return false;
else if(t->element == e)
return true;
else if (e<t->element)
return tree_contains(t->left,e);
else
return tree_contains(t->right,e);
}
tree_node* tree_add(tree_node* t, generic e) {
/*TODO: Complete this function!*/
if(t==NULL)
t = new_tree_node(e);
else if(e == t->element)
return t;
else if(e > (t->element))
{
t->right = tree_add(t->right,e);
}
else if(e < (t->element))
{
t->left = tree_add(t->left,e);
}
return t;
}
tree_node* tree_remove(tree_node* t, generic e) {
/*TODO: Complete this function!*/
if (t == NULL) return t;
else if (e < t->element)
t->left = tree_remove(t->left, e);
else if (e > t->element)
t->right = tree_remove(t->right, e);
else
{
if (t->left == NULL)
{
tree_node *temp = t->right;
free(t);
return temp;
}
else if (t->right == NULL)
{
tree_node *temp = t->left;
free(t);
return temp;
}
else {
tree_node* current = t->right;
tree_node* temp = t->right;
while (current->left != NULL)
current = current->left;
t->element = current->element;
while (temp->left->left != NULL)
temp = temp->left;
temp->left = current->right;
free(current);
}
}
return t;
}
/* End Tree Storage and Access */
/* Size and Index */
/* Return the size of the tree rooted at the given node.
* The size of a tree is the number of nodes it contains.
* This function should work on subtrees, not just the root.
* If t is NULL, it is to be treated as an empty tree and you should
* return 0.
* A single node is a tree of size 1.*/
int tree_size(tree_node* t) {
/*TODO: Complete this function!*/
if (t==NULL)
return 0;
else
return(tree_size(t->left) + 1 + tree_size(t->right));
}
/* Return the element at the given index in the given tree.
* To be clear, imagine the tree is a sorted array, and you are
* to return the element at the given index.
*
* Assume indexing is zero based; if index is zero then the minimum
* element should be returned, for example. If index is one then
* the second smallest element should bereturned, and so on.*/
generic tree_get_at_index(tree_node* t, int index) {
//assert(index >=0 && index < tree_size(t));
/*TODO: Complete this function!*/
//tree_node* new_node = t;
// int min = 0;
// int max = tree_size(t);
// int current = (min+max)/2;
int current = index;
printf("tree size: %d \n", tree_size(t));
//while( new_node != NULL){
if(current == (tree_size(t)-1)){
return t->element;
printf("index = tree size \n");
}
else if(index < (tree_size(t->left))){
//current--;
return tree_get_at_index(t->left, index);
printf("index < tree size \n"); //= new_node->right;
}
else if(index > (tree_size(t->left))){
return tree_get_at_index(t->right, index);
printf("index > tree size \n");
}
return t->element;
//return (generic)0;
}
/* End Size and Index */
We will try filling a virtual array, as you know the size of each subtree you could skip the indexes
generic tree_get_at_index(tree_node* t, int index) {
// sanity check
assert(t);
assert(index > 0);
int leftCount=tree_size(t->left);
if(index < leftCount ) {
// good chance that the node we seek is in the left children
return tree_get_at_index(t->left, index);
}
if(index==leftCount) {
// looking at the "middle" of the sub tree
return t->element;
}
// else look at the right sub tree as it was its own array
return tree_get_at_index(t->right, index - leftCount - 1);
}
generic tree_get_at_index(tree_node* t, int index) {
assert(index >=0 && index <= tree_size(t));//I don't know how you define the tree_size function,but,according to the "if" below,you need to add equal mark
printf("tree size: %d \n", tree_size(t));
//while( new_node != NULL){
if(index == tree_size(t)){
return t->element;
}
else if(index <= tree_size(t->left)){//I think you miss the equal situation here
//current--;
return tree_get_at_index(t->left, index); //= new_node->right;
}
else /*if(index > tree_size(t->left))*/{//do not need any condition here
return tree_get_at_index(t->right, index);
}
// return t->element; //unnecessary
//return (generic)0;
}
The successor of an element in a BST is the element's successor in the
sorted order determined by the inorder traversal. Finding the
successor when each node has a pointer to its parent node is presented
in CLRS's algorithm textbook (Introduction to Algorithms by MIT
press).
Is there a way to find the first value that is bigger than X without parent in the struct? Like:
typedef struct tree tree;
struct tree{
int value;
tree *left;
tree *right;
};
//Function:
tree *find_first_bigger(tree *t, int x){}
I tried working with:
tree *find_first_bigger(tree *t, int x){
if(t == NULL)
return NULL;
if((*t)->value > x)
find_first_bigger((*t)->left, x);
else if((*t)->value < x)
find_first_bigger((*t)->right), x);
else if((*t)->value == x){
if((*t)->right != NULL)
return tree_first_bigger((*t)->right);
else
return tree;
}
}
With this example(it's using letter but there its not a problem), if I try to search the first bigger than N(It should return me O) but it returns me N.
You have done 90% of the job.Allow me to do the remaining 10%.
Since t is a pointer to structure you should use t->left instead of (*t)->left and same applies while accessing right and value fields of the struct.
Now, Just modify your function as:
Add this as first line of your function
static tree* PTR=NULL;
Modify the second if condition as:
if(t->value > x)
{
PTR=t;
find_first_bigger(t->left, x);
}
Modify the second else if condition as:
else if(t->value == x)
{
if(t->right != NULL)
{
t=t->right;
while(t->left!=NULL)
t=t->left;
return t;
}
else return PTR;
}
Hence the correct function is
tree *find_first_bigger(tree *t, int x)
{
static tree* PTR=NULL;
if(t == NULL)
return NULL;
if(t->value > x)
{
PTR=t;
find_first_bigger(t->left, x);
}
else if(t->value < x)
find_first_bigger(t->right, x);
else if(t->value == x)
{
if(t->right != NULL)
{
t=t->right;
while(t->left!=NULL)
t=t->left;
return t;
}
else return PTR;
}
}
In the main function if pointer returned is NULL, this means that :the key itself is the largest key. Feel free for any queries.
I haven't tested this, but I think it should work. Let me know if it is wrong.
//c++ 11
#include<iostream>
using namespace std;
struct BSTNode{
int val;
BSTNode* left;
BSTNode* right;
};
int FindJustLarger(BSTNode*& node, int token, int sofarlarge){
// for invalid inputs it will return intial value of sofarlarge
// By invalid input I mean token > largest value in BST
if(node == nullptr)
return sofarlarge;
else if(node->val > token){
sofarlarge = node->val;
return FindJustLarger(node->left, token, sofarlarge);}
else
return FindJustLarger(node->right, token, sofarlarge);}
int main(){
BSTNode* head = new BSTNode{5, nullptr, nullptr};
FindJustLarger(head, 5, NULL);
delete head;
return 0;}
Some changes you can do in your code:
You have to return the values from the recursive calls
If the value is not found, return NULL. This means returning NULL if t->right == NULL on the last if.
When going to the left, if the value is not found there, the answer must be the node itself. In the case of N, it is the last node where we turn left: O. If it were P, the answer would be T itself.
After all those changes, the code should look like this:
tree *find_first_bigger(tree *t, int x){
if(t == NULL)
return NULL;
if(t->value > x) {
tree *answer = find_first_bigger(t->left, x);
if (answer != NULL)
return answer;
return t;
} else if(t->value < x) {
return find_first_bigger(t->right, x);
} else if(t->value == x) {
if (t->right != NULL)
return tree_first_bigger(t->right);
return NULL;
}
}
You can find the entire code I used to test in this gist.
In your question, you seemed to indicate that you want to find out InOrderSuccessor() of the the given value 'x'.
If 'x' does not necessarily exist in the tree, we need to change the algorithm. Given the example you provided and the problem statement, here is code for finding the next element in a BST.
The key cases are :
No greater element exists, because 'x' is the biggest.
'x' has a right child ?
YES: get left-most child of x's right sub-tree.
NO : return parent.
Key observation is that we don't update the parent pointer, whenever we go right in the tree.
tree *ptr = root;
tree *prnt = NULL;
while (ptr != NULL) {
if (x == ptr->key) {
if (ptr->right != NULL) {
return GetLeftMostChild(ptr->right);
} else {
return prnt;
}
} else if (x > ptr->key) {
ptr = ptr->right;
} else {
prnt = ptr;
ptr = ptr->left;
}
}
Here is the definition for leftMostChild()
tree *GetLeftMostChild(tree *n) {
tree *ptr = n;
while (ptr->left != NULL) {
ptr = ptr->left;
}
return ptr;
}
I did my best with this program but I could not know where is the error?? I'll explain the program. In this program I should implement a stack of integers as linked list, using a global variable to point to the top of the stack by using these methods:
int push(int i);
push i on the stack, return 1 if successful else return 0.
int pop();
pop number from stack. if stack empty return 0;
I did create new method call int stackEmpty(); and the two method above.
Every time I run my program it's push the numbers into the stack but the pop doesn't work. Here my code:::
#include <stdio.h>
#include <stdlib.h>
typedef struct stack Stack;
struct stack
{
int number;
Stack *next;
};
Stack *top = NULL;
int push(int i);
int count();
int stackEmpty();
int pop();
int main()
{
char op;
int i, x;
printf("Welcome to my stack\n");
printf("p to pop, s to push, c to count, q to quit\n");
while (op != 'q')
{
scanf("%c", &op);
if (op == 'p')
{
x = pop();
if (x == 0)
{
printf("Stack is empty\n");
}
else
{
printf("%d popped\n", pop());
}
}
else if (op == 'c')
{
i = count();
printf("%d numbers on stack\n", i);
}
else if (op == 's')
{
printf("Enter number: ");
scanf("%d", &i);
x = push(i);
if (x == 1 || x == 2)
{
printf("%d puched :: state%d\n", i, x);
}
else
{
printf("faill %d\n", x);
}
}
else if (op == 'q')
{
return 0;
}
}
return 0;
}
int stackEmpty()
{
if (top == NULL)
{
return 1;
}
else
{
return 0;
}
}
int count()
{
int counter = 0;
if (top == NULL)
{
return counter;
}
else
{
while (top != NULL)
{
top = top->next;
counter++;
}
return counter;
}
}
int push(int i)
{
Stack *head;
Stack *next;
Stack *new;
int state;
int m;
head = top;
new = (Stack *) malloc(sizeof(Stack));
if (new == NULL)
{
state = 0;
} new->number = i;
m = stackEmpty();
if (m == 1)
{
head = new;
top = head;
head->next = NULL;
state = 1;
}
else
{
while (head != NULL)
{
if ((next = head->next) == NULL)
next = new;
next->next = NULL;
state = 2;
break;
head = top->next;
next = head->next;
}
top = head;
}
return state;
}
int pop()
{
Stack *head;
int state;
int m;
head = top;
if (head == NULL)
{
state = 0;
}
m = stackEmpty();
if (m == 1)
{
state = 0;
}
else
{
state = head->number;
top = head->next;
free(head);
}
return state;
}
Several problems:
top is your supposed head of the stack I assume. In count you advance top until it is NULL - thus once you called count you have "lost" your stack.
A stack is a LIFO queue (last in first out). Your push would implement a FIFO (first in first out) by appending new elements at the end.
Your push is not actually adding anything to the list. You are just assiging new to next but you are not pointing to next from anywhere in your list.
When using pop you are calling it twice (once for removing the element and once for printing). Therefore you remove two elements whenever you go down that code path. A better implementation would be to write a peek function which returns the top element without removing it and the pop function simply removes it (indicating success with 1 and fail with 0)
A push for a stack goes like this:
Create a new element
Point to your current head as the next element
Make your new element the new head of the stack
No loop needed. It's an O(1) operation.
You are not pushing correctly. You are changing next which is a local variable. you are not changing the "next" value in you list tail.
One problem is that you pop(), then check result, then pop() again while printing. You're popping twice for each time you try to print.
Another error:
while (head != NULL)
{
if ((next = head->next) == NULL)
next = new;
next->next = NULL;
state = 2;
break;
head = top->next;
next = head->next;
}
Should be:
while (head != NULL)
{
if ((next = head->next) == NULL)
{
next = new;
next->next = NULL;
state = 2;
break;
}
head = top->next;
next = head->next;
}
At least, that's what your original indentation seems to indicate.