Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I need to "translate" basic graph algorithms, from C to a hybrid of C and C++ where I use the new operator .
I need help "translating" the construction of this nested structs that I found on the yale223 notes.
I will appreciate any help.
struct graph {
int n; /* number of vertices */
int m; /* number of edges */
struct successors {
int d; /* number of successors */
int len; /* number of slots in array */
int isSorted; /* true if list is already sorted */
int list[]; /* actual list of successors starts here */
} *alist[];
};
g = malloc(sizeof(struct graph) + sizeof(struct successors *) * n);
assert(g);
Not sure what you want, but following might help, using std::vector:
struct successors {
std::vector<int> list; /* actual list of successors starts here */
// int d; /* number of successors */ // Already stored in vector
int len; /* number of slots in array */
bool isSorted; /* true if list is already sorted */
};
struct graph {
int n; /* number of vertices */
int m; /* number of edges */
std::vector<successors> alist;
};
Related
I am confused, the function binaryTreeToBST that has the below-mentioned operations and function call. Why are we not adding time complexities of each called function instead of taking only the time complexity of sort (step 3 below)?
countNodes
Creating temp array arr[] that stores inorder traversal of the tree. (takes O(n) )
sort the temp array arr[]. This step takes O(nlogn) time.
Again do inorder traversal to convert BT to BST(takes O(n) )
/* A program to convert Binary Tree to Binary Search Tree */
#include <stdio.h>
#include <stdlib.h>
/* A binary tree node structure */
struct node {
int data;
struct node* left;
struct node* right;
};
/* A helper function that stores inorder traversal of a tree rooted
with node */
void storeInorder(struct node* node, int inorder[], int* index_ptr)
{
// Base Case
if (node == NULL)
return;
/* first store the left subtree */
storeInorder(node->left, inorder, index_ptr);
/* Copy the root's data */
inorder[*index_ptr] = node->data;
(*index_ptr)++; // increase index for next entry
/* finally store the right subtree */
storeInorder(node->right, inorder, index_ptr);
}
/* A helper function to count nodes in a Binary Tree */
int countNodes(struct node* root)
{
if (root == NULL)
return 0;
return countNodes(root->left) + countNodes(root->right) + 1;
}
// Following function is needed for library function qsort()
int compare(const void* a, const void* b)
{
return (*(int*)a - *(int*)b);
}
/* A helper function that copies contents of arr[] to Binary Tree.
This function basically does Inorder traversal of Binary Tree and
one by one copy arr[] elements to Binary Tree nodes */
void arrayToBST(int* arr, struct node* root, int* index_ptr)
{
// Base Case
if (root == NULL)
return;
/* first update the left subtree */
arrayToBST(arr, root->left, index_ptr);
/* Now update root's data and increment index */
root->data = arr[*index_ptr];
(*index_ptr)++;
/* finally update the right subtree */
arrayToBST(arr, root->right, index_ptr);
}
// This function converts a given Binary Tree to BST
void binaryTreeToBST(struct node* root)
{
// base case: tree is empty
if (root == NULL)
return;
/* Count the number of nodes in Binary Tree so that
we know the size of temporary array to be created */
int n = countNodes(root);
// Create a temp array arr[] and store inorder traversal of tree in arr[]
int* arr = new int[n];
int i = 0;
storeInorder(root, arr, &i);
// Sort the array using library function for quick sort
qsort(arr, n, sizeof(arr[0]), compare);
// Copy array elements back to Binary Tree
i = 0;
arrayToBST(arr, root, &i);
// delete dynamically allocated memory to avoid memory leak
delete[] arr;
}
/* Utility function to create a new Binary Tree node */
struct node* newNode(int data)
{
struct node* temp = new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
/* Utility function to print inorder traversal of Binary Tree */
void printInorder(struct node* node)
{
if (node == NULL)
return;
/* first recur on left child */
printInorder(node->left);
/* then print the data of node */
printf("%d ", node->data);
/* now recur on right child */
printInorder(node->right);
}
/* Driver function to test above functions */
int main()
{
struct node* root = NULL;
/* Constructing tree given in the above figure
10
/ \
30 15
/ \
20 5 */
root = newNode(10);
root->left = newNode(30);
root->right = newNode(15);
root->left->left = newNode(20);
root->right->right = newNode(5);
// convert Binary Tree to BST
binaryTreeToBST(root);
printf("Following is Inorder Traversal of the converted BST: \n");
printInorder(root);
return 0;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I just ended my first exams session, passed (thanks to you).
I have one more question for you: I have to find the max of an array of struct and then printf the element of the array that has the max value in it, using a recursive algorithm. I've been smashing my head on the keyboard for about 1 week just to solve this, but I cannot seem to be able to do it. Can you help me?
Here's the code:
PLEASE, DON'T CARE ABOUT THOSE STRCPY, ty.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char autori[100];
char titolo[100];
int anno;
int codice;
float prezzo;
char stato[50];
} libro;
int massimo(int m, int n );
libro ricorsivo(libro a[], int len);
void main()
{
libro max;
int len=30;
libro elenco[100];
strcpy(elenco[0].autori,"Angelo Ciaramella e Giulio Giunta");
strcpy(elenco[0].titolo,"Manuale di Programmazione in C");
elenco[0].anno=2009;
elenco[0].codice=0;
elenco[0].prezzo=0.0;
strcpy(elenco[0].stato,"Disponibile");
max=ricorsivo(elenco, len);
printf ("il massimo vale %d", max);
}
libro ricorsivo(libro a[], int len)
{
if (len==1)
return a[0];
else
return massimo(a.prezzo[len-1],ricorsivo(a,len-1));
}
int massimo(int m, int n)
{
if (n>m)
return n;
else if (m>n)
return m;
}
The algorithm is incomplete, I know, but the most problematic parts are those functions. I hope you can help me, thank you.
Here are some hints that should help you fix the code:
Firstly, your massimo (max) function is defined incorrectly. In the case where m == n this function returns nothing, this is not allowed. What you want is if n > m you return n otherwise simply return m, i.e.
int max(int m, int n) { return n > m ? n : m; }
Next, in your recursive function you have a few type errors in this line:
return massimo(a.prezzo[len-1], recorsivo(a, len-1))
a is not of type libro, it is of type libro[] so it is not going to have a prezzo field.
If a were of type libro, and you accessed its prezzo field, then that has type float, and so it would be incorrect to perform an array index on it.
If a.prezzo[len-1] did produce the prezzo value of the len-1th element of the array, then that would have type float, but your massimo function accepts only ints.
ricorsivo(a, len-1) returns a libro and it is being passed into massimo which takes an int.
To fix these issues try the following:
Remove your massimo function, you don't need it.
In the recursive case of your recursive function
Call it recursively to get the max from the rest of the array.
Compare the prezzo value from the max of the rest of the array, with the prezzo value from the element at len-1.
Return the libro with the larger prezzo.
You should be able to translate the above into some pretty straightforward C code.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Given a set of characters and a positive integer p, I have to print all possible strings of length p that can be formed from the given set.
for eg: if the set is {a,b}
and the value of p is 2
Output is: aa,ab,ba,bb
I know that for a given set of size n, there will be np possible strings of length p.
What is the best method that can be used to print all the possible strings.? I just want an approach to solve.
I'm using C.
A possible approach could be to start from an empty string and add characters one by one to it using a recursive function and printing it.
Here is my code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void print_string(char str[],char new_str[],int current_len,int n,int len)
{
/*
str=orignal set,
new_str=empty char array,
current_len=0(Intially)
n=no of elements to be used
len=the value of p given*/
if(current_len==len)//print string when length is equal to p
{
printf("%s\n",new_str);
return;
}
else
{
int i;
for(i=0;i<n;i++)
{
new_str[current_len]=str[i];
print_string(str,new_str,current_len+1,n,len);
}
}
}
int main()
{
char set[]={'a','b'};
char arr[10]="";
print_string(set,arr,0,2,2);
return 0;
}
output:
aa
ab
ba
bb
You may use a vector, let's call it : string [ p ].
If p is for eg. 7, you will have :
string = [ 0, 0, 0, 0, 0, 0, 0].
The index 0, is for the first char, index 1 for the second and so on until N.
for string : "smthing" , you will have : 0 - s , 1 - m, 2-t, 3-h, 4-i, 5-n, 6-g.
You may use a : while ( all elements in string != 'n' ) {
for the initial string ( string[p]={0} ) you will have : "sssssss" , the first string we built till yes.
you will always add +1 at index each loop and if index = n, you will reset it, like this [0 0 9] -> [0 1 0] if n=9 for exemple.
..and you will have all the posible combination by interpreting the index like i described;
}
You want to list your strings in lexicographical order. Fastest way (and minimal memory usage) is to implement a function to compute the next string to a given one. Here is some temptative code:
char first_char='a';
int n_chars = 2;
int p=2;
char result[100];
int i,j;
/* fill-in first string */
for(i=0;i<p;++i) result[i]=first_char;
result[i]=0; /* string terminator */
printf("%s\n",result); /* print first string */
while(1) {
/* find last character of result which can be incremented
for (j=p-1;j>=0 && result[j]!=first_char + n_chars -1;j--);
if (j<0) break; /* this was the last string */
result[j]++; /* increment j-th character
for(j++;j<p;++j) result[j]=first_char; /* reset following chars */
/* print current string */
printf("%s\n",result);
}
Can someone explain to me please, how this code works :
http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c
I don't understand the algorithm used in this post. Thanks
Merge sort is often preferred for sorting a linked list. The slow random-access performance of a linked list makes some other algorithms (such as quicksort) perform poorly, and others (such as heapsort) completely impossible.
Let head be the first node of the linked list to be sorted and headRef be the pointer to head. Note that we need a reference to head in MergeSort() as the below implementation changes next links to sort the linked lists (not data at the nodes), so head node has to be changed if the data at original head is not the smallest value in linked list.
MergeSort(headRef)
1) If head is NULL or there is only one element in the Linked List
then return.
2) Else divide the linked list into two halves.
FrontBackSplit(head, &a, &b); /* a and b are two halves */
3) Sort the two halves a and b.
MergeSort(a);
MergeSort(b);
4) Merge the sorted a and b (using SortedMerge() discussed here)
and update the head pointer using headRef.
*headRef = SortedMerge(a, b);
/* Link list node */
struct node
{
int data;
struct node* next;
};
/* function prototypes */
struct node* SortedMerge(struct node* a, struct node* b);
void FrontBackSplit(struct node* source,
struct node** frontRef, struct node** backRef);
/* sorts the linked list by changing next pointers (not data) */
void MergeSort(struct node** headRef)
{
struct node* head = *headRef;
struct node* a;
struct node* b;
/* Base case -- length 0 or 1 */
if ((head == NULL) || (head->next == NULL))
{
return;
}
/* Split head into 'a' and 'b' sublists */
FrontBackSplit(head, &a, &b);
/* Recursively sort the sublists */
MergeSort(&a);
MergeSort(&b);
/* answer = merge the two sorted lists together */
*headRef = SortedMerge(a, b);
}
/* See http://geeksforgeeks.org/?p=3622 for details of this
function */
struct node* SortedMerge(struct node* a, struct node* b)
{
struct node* result = NULL;
/* Base cases */
if (a == NULL)
return(b);
else if (b==NULL)
return(a);
/* Pick either a or b, and recur */
if (a->data data)
{
result = a;
result->next = SortedMerge(a->next, b);
}
else
{
result = b;
result->next = SortedMerge(a, b->next);
}
return(result);
}
/* UTILITY FUNCTIONS */
/* Split the nodes of the given list into front and back halves,
and return the two lists using the reference parameters.
If the length is odd, the extra node should go in the front list.
Uses the fast/slow pointer strategy. */
void FrontBackSplit(struct node* source,
struct node** frontRef, struct node** backRef)
{
struct node* fast;
struct node* slow;
if (source==NULL || source->next==NULL)
{
/* length next;
/* Advance 'fast' two nodes, and advance 'slow' one node */
while (fast != NULL)
{
fast = fast->next;
if (fast != NULL)
{
slow = slow->next;
fast = fast->next;
}
}
/* 'slow' is before the midpoint in the list, so split it in two
at that point. */
*frontRef = source;
*backRef = slow->next;
slow->next = NULL;
}
}
/* Function to print nodes in a given linked list */
void printList(struct node *node)
{
while(node!=NULL)
{
printf("%d ", node->data);
node = node->next;
}
}
/* Function to insert a node at the beginging of the linked list */
void push(struct node** head_ref, int new_data)
{
/* allocate node */
struct node* new_node =
(struct node*) malloc(sizeof(struct node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Drier program to test above functions*/
int main()
{
/* Start with the empty list */
struct node* res = NULL;
struct node* a = NULL;
struct node* b = NULL;
/* Let us create a unsorted linked lists to test the functions
Created lists shall be a: 2->3->20->5->10->15 */
push(&a, 15);
push(&a, 10);
push(&a, 5);
push(&a, 20);
push(&a, 3);
push(&a, 2);
/* Remove duplicates from linked list */
MergeSort(&a);
printf("\n Sorted Linked List is: \n");
printList(a);
getchar();
return 0;
}
Try imaging all the merges that are performed in a normal merge sort on an array: first, elements are paired up and merged into sorted subarray of length two, then these subarray of length two are paired up and merged into sorted subarray of length four and so on. Notice the length of the subarray: 1, 2, 4, and so on, let's call this instep, which doubles in each iteration.
At any point, p points to a list of length instep, q points to a list of length instep or smaller (we may hit the end of the list), and q immediately follows p. They form a pair of subarray as mentioned above. We do a merge on p and q to get a sorted list of length psize + qsize starting from p. We than move p and q to the next pair, and so on. Once we are done with the whole list, we double instep and start merging longer sorted list.
Please note that there is no limitation of memory.
I need to insert int from 1 to 1000.
I can do the each of the following operations in constant order of time:
push():adds to the top
pop():removes the top element
getMax(): returns the max element
Please suggest me appropriate datastructure.
Since there is no limitation of memory, I will use 2 vectors - one for the actual data on the stack, and the other to keep track of the max at every state of the stack.
For simplicity sake I'm assuming this stack holds only +ve ints.
I know this doesn't have any error checking. But I am just providing the data structure idea here, not the full-fledged solution.
class StackWithMax
{
public:
StackWithMax() : top(-1), currentMax(0) { }
void push(int x);
int pop();
int getMax() { return m[top]; }
private:
vector<int> v; // to store the actual elements
vector<int> m; // to store the max element at each state
int top;
int currentMax;
};
void StackWithMax::push(int x)
{
v[++top] = x;
m[top] = max(x, currentMax);
}
int StackWithMax::pop()
{
int x = v[top--];
currentMax = m[top];
return x;
}
Use normal stack structure and additional array for counters
int c[1..1000] and variable int maxVal=0.
In code add actions after stack operations:
On push(x) -> c[x]++ ; maxVal = max(x,maxVal)
On pop():x -> c[x]-- ; if (c[x] == 0) { j=x; while(c[--j] == 0); maxVal = j; }
maxVal should have always maximum value.
Maybe I am wrong, this should have amortized computational complexity O(1).
It has been a long time since I have been analysing algorithms.