Sorting two stacks by using structs - sorting

There are 3 stacks - A, B, C
Stacks A and B are sorted (the number on the top of the stack is the biggest). Stack C is Empty Only 5 operation are allowed:
push,
pop,
top,
is_empty,
create
We need to write a function that receives the stacks A and B, moves all the numbers in stacks A and B to stack C and stack C must be sorted (biggest Number is on top).
I have the algorithm :
Compare top of A with top of B
Pop the least element and push to stack C
Repeat step 2 until any of the stack ( A or B) becomes empty
Move remaining elements from non-empty stack to C. Now you have all the elements in C but in ascending order. (That is least element at top).
Move all the elements from C to A. (Contents in A are in descending order)
Move all the elements from A to B. (Contents in B are in ascending order)
Move all the elements from B to C.
and i started to write the code but there are errors and i don't know why !
the code :
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define MAX_MEMBERS 10
typedef struct
{
int num;
}ITEM;
typedef struct
{
ITEM a[MAX_MEMBERS];
int top;
}STACK;
void create_stack(STACK *s)
{
s->top=-1;
}
int is_empty(STACK *s)
{
return s->top==-1;
}
int is_full(STACK *s)
{
return s->top==MAX_MEMBERS-1;
}
ITEM pop(STACK *s)
{
return s->a[s->top--];
}
void (STACK *s,ITEM *item)
{
s->a[++s->top]=*item;
}
ITEM top(STACK *s)
{
return s->a[s->top];
}
void sort (STACK *a,STACK *b,STACK *c)
{
while(!is_empty(&a)||!is_empty(&b))
if(top(&a)>top(&b))
push(&c,pop(&b));
if(!is_empty(&a))
{
while(!is_empty(&a))
push(&c,pop(&a));
}
else
{
while(!is_empty(&b))
push(&c,pop(&b));
}
while(!is_empty(&c))
push(&a,pop(&c));
while(!is_empty(&a))
push(&b,pop(&a));
while(!is_empty(&b))
push(&c,pop(&b));
}
void main(void)
{
STACK a,b,c;
create_stack(&a);
create_stack(&b);
create_stack(&c);
sort(&a,&b,&c);
}

You should pop the highest element and push it to C.
To push all elements onto C in reversed order you need the highest element at the bottom of C (this value must be pushed first). If a > b Then: pop a, push c.
Anyway, your code doesn't seem to be very safe. Have a look at the following:
while(!is_empty(&a)||!is_empty(&b))
if(top(&a)>top(&b))
let's assume that a is empty and b is not so that a.top equals to -1 and b.top is in range 0 to MAX_MEMBERS - 1. Since one of the stacks is not empty the condition is true.
By calling top(&a) following code is executed:
return a[-1]; //Error: Index out of bounds
This is how your code is resolved.
is_empty(&a) returns true
!is_empty(&a) returns false
(false || true) returns true
while(false || true)
if( top(&a) > top(&b) )
Anyway, i doubt that your code does even compile.
void (STACK *s,ITEM *item)
{
s->a[++s->top]=*item;
}
This should be that:
void push(STACK *s,ITEM *item)
{
s->a[++s->top]=*item;
}
Also consider that:
void main(void)
{
STACK a,b,c;
create_stack(&a); //stack a is created, contains no elements
create_stack(&b); //stack b is created, contains no elements
create_stack(&c); //stack c is created, contains no elements
sort(&a,&b,&c); //sort which elements of the stack?
}

Related

Time Complexity and Space Complexity of Tower of Hanoi problem iterative algorithm?

I am unable to find the Time Complexity and Space Complexity of Tower of Hanoi problem using iterative algorithm.
Can anyone help, please?
Iterative Algorithm:
Calculate the total number of moves required i.e. "pow(2, n) - 1" here n is number of disks.
If number of disks (i.e. n) is even then interchange destination
pole and auxiliary pole.
for i = 1 to total number of moves:
if i%3 == 1:
legal movement of top disk between source pole and
destination pole
if i%3 == 2:
legal movement top disk between source pole and
auxiliary pole
if i%3 == 0:
legal movement top disk between auxiliary pole
and destination pole
code -
// C Program for Iterative Tower of Hanoi
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
// A structure to represent a stack
struct Stack
{
unsigned capacity;
int top;
int *array;
};
// function to create a stack of given capacity.
struct Stack* createStack(unsigned capacity)
{
struct Stack* stack =
(struct Stack*) malloc(sizeof(struct Stack));
stack -> capacity = capacity;
stack -> top = -1;
stack -> array =
(int*) malloc(stack -> capacity * sizeof(int));
return stack;
}
// Stack is full when top is equal to the last index
int isFull(struct Stack* stack)
{
return (stack->top == stack->capacity - 1);
}
// Stack is empty when top is equal to -1
int isEmpty(struct Stack* stack)
{
return (stack->top == -1);
}
// Function to add an item to stack. It increases
// top by 1
void push(struct Stack *stack, int item)
{
if (isFull(stack))
return;
stack -> array[++stack -> top] = item;
}
// Function to remove an item from stack. It
// decreases top by 1
int pop(struct Stack* stack)
{
if (isEmpty(stack))
return INT_MIN;
return stack -> array[stack -> top--];
}
//Function to show the movement of disks
void moveDisk(char fromPeg, char toPeg, int disk)
{
printf("Move the disk %d from \'%c\' to \'%c\'\n",
disk, fromPeg, toPeg);
}
// Function to implement legal movement between
// two poles
void moveDisksBetweenTwoPoles(struct Stack *src,
struct Stack *dest, char s, char d)
{
int pole1TopDisk = pop(src);
int pole2TopDisk = pop(dest);
// When pole 1 is empty
if (pole1TopDisk == INT_MIN)
{
push(src, pole2TopDisk);
moveDisk(d, s, pole2TopDisk);
}
// When pole2 pole is empty
else if (pole2TopDisk == INT_MIN)
{
push(dest, pole1TopDisk);
moveDisk(s, d, pole1TopDisk);
}
// When top disk of pole1 > top disk of pole2
else if (pole1TopDisk > pole2TopDisk)
{
push(src, pole1TopDisk);
push(src, pole2TopDisk);
moveDisk(d, s, pole2TopDisk);
}
// When top disk of pole1 < top disk of pole2
else
{
push(dest, pole2TopDisk);
push(dest, pole1TopDisk);
moveDisk(s, d, pole1TopDisk);
}
}
//Function to implement TOH puzzle
void tohIterative(int num_of_disks, struct Stack
*src, struct Stack *aux,
struct Stack *dest)
{
int i, total_num_of_moves;
char s = 'S', d = 'D', a = 'A';
//If number of disks is even, then interchange
//destination pole and auxiliary pole
if (num_of_disks % 2 == 0)
{
char temp = d;
d = a;
a = temp;
}
total_num_of_moves = pow(2, num_of_disks) - 1;
//Larger disks will be pushed first
for (i = num_of_disks; i >= 1; i--)
push(src, i);
for (i = 1; i <= total_num_of_moves; i++)
{
if (i % 3 == 1)
moveDisksBetweenTwoPoles(src, dest, s, d);
else if (i % 3 == 2)
moveDisksBetweenTwoPoles(src, aux, s, a);
else if (i % 3 == 0)
moveDisksBetweenTwoPoles(aux, dest, a, d);
}
}
// Driver Program
int main()
{
// Input: number of disks
unsigned num_of_disks = 3;
struct Stack *src, *dest, *aux;
// Create three stacks of size 'num_of_disks'
// to hold the disks
src = createStack(num_of_disks);
aux = createStack(num_of_disks);
dest = createStack(num_of_disks);
tohIterative(num_of_disks, src, aux, dest);
return 0;
}
The code of Tower of Hanoi iterative algorithm is above. Please, help me.
Let's define 𝑛 as the number of discs.
The time complexity is O(2𝑛), because that is the number of iterations done in the only loops present in the code, while all other code runs in constant time.
The space complexity can be split up in two parts:
The "towers" themselves (stacks) have a O(𝑛) space complexity
The auxiliary space has a O(1) space complexity as there are no other vectors, and the call stack has a fixed size (no dynamic recursion)
So combined this has a O(𝑛) space complexity.
It depends, because the question is fundamentally ambiguous. The most interesting part of the tower-of-Hanoi algorithm is that it is a pseudo-random irrational structure with an exponential information, but if you move the tower from left to right, and then move it from right to left, the time complexity is exactly 0.
For example, there is no fast algorithm that can compute the square root of 5.
This means that the question is fundamentally subjective based on what you mean by the tower of Hanoi and how much information you really want to extract.

Function to insert an integer into a circular linked _list in ascending order

I am writing a function to insert an integer into a circular linked _list in ascending order whose elements are sorted in ascending order (smallest to largest).
The input to the function insertSortedList is a pointer start to some node in the circular list and an integer n between 0 and 100. Return a pointer to the newly inserted node.
The structure to follow for a node of the circular linked list is-
Struct CNode;
Typedef struct CNode cnode;
Struct CNode
{
Int value;
Cnode* next;
};
Cnode* insertSortedList (cnode* start,int n)
{
//WRITE YOUR CODE HERE
}
//FUNCTION SIGNATURE ENDS
Test Case 1:
Input:
[3->4->6->1->2->^],5
Expected Return Value:
[5->6->1->2->3->4->^]
Test Case 2:
Input:
[1->2->3->4->5->^],0
Expected Return Value:
[0->1->2->3->4->5->^]
Here's my code:
Cnode* insertSortedList (cnode* start,int n)
{
int count=1,i,count1=0;
Cnode* temp=start;
Cnode* temp1=start;
Cnode* temp2=start;
Cnode* newHead=NULL;
while(temp!=NULL)
{
temp=temp->next;
count ++;
}
int arr[count];
while(temp2!=NULL)
{
for(j=0;j<count;j++)
{
arr[j]=temp->data;
temp2=temp2->next;
}
}
while(n>=temp2->value)
{
temp2=temp2->next;
}
newHead=temp2;
for(i=0;i<count;i++)
{
Cnode* newNode=new Cnode();
newNode->data=arr[i];
newNode->next=NULL;
}
}
You said it's a circular linked-list but you are checking for temp != null. It should be temp→next != start.
Its not so complicated at all. Given a pointer to any element in a circular linked list, whose elements are already in ascending order, we just need to find the location of the new element, which can be done in a few lines. Simple Java code -
CNode prev = start;
CNode next = start.next;
while(true){
if(prev.value <= n && n <= next.value) break;
prev=next; next=next.next;
}
CNode node = new CNode();
node.value = n;
prev.next=node; node.next=next;
return node;

Linked List Merge Sort Exaplanation

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.

Custom Data Structure for push, pop and finding minimum

I was just asked an interview question with company A as follows:
Question : Design a data structure in which you have 3 operations, push, pop and find the minimum. You should be doing all the 3 operations in constant time.
My Answer : I would use a linked list in which i can do insertion and removal in constant time and i would use an extra memory to store the minimum.
He came up with a second question saying, if you pop the minimum, how do you find the second minimum? again, in constant time.
What would you tell him?
Minimum stack question - http://courses.csail.mit.edu/iap/interview/Hacking_a_Google_Interview_Practice_Questions_Person_A.pdf
From the PDF:
Question: Minimum Stack
Describe a stack data structure that supports "push", "pop", and "find minimum"
operations. "Find minimum" returns the smallest element in the stack.
Good Answer: Store two stacks, one of which contains all of the items in the stack
and one of which is a stack of minima. To push an element, push it onto the first
stack. Check whether it is smaller than the top item on the second stack; if so, push
it onto the second stack. To pop an item, pop it from the first stack. If it is the top
element of the second stack, pop it from the second stack. To find the minimum
element, simply return the element on the top of the second stack. Each operation
takes O(1) time.
What if you do a linked list, like you said, but also store the current minimum value. When you add a new number it looks at the previous min and changes the current min to the current value if the current value is lower.
E.g... Assume you have the data: 3, 6, 4, 2, 7, 1. Then this is what the list would look like
value|min
3|3 -> 6|3 -> 4|3 -> 2|2 -> 7|2 -> 1|1
That'll keep track of the mins as you add/remove items.
EDIT:
I mentioned going backwards, it would be something like this:
1|1 -> 7|2 -> 2|2 -> 4|3 -> 6|3 -> 3|3
Then you wouln't need the "footer".
Let every node keep another reference to the previously smallest item. So, when you pop the smallest item, you can restore the previously smallest. Because you can only push and pop it will be the correct node.
Here is the C code which implements the above algorithm given by Bryce Siedschlaw:
#include<stdio.h>
#include<stdlib.h>
#define minimumOf(a,b) (a<b) ? a : b;
struct node{
int data;
struct node* next;
int min;
};
void push(struct node **head_ref, int new_data){
struct node* new_node = (struct node *)malloc(sizeof(struct node));
new_node->data = new_data;
if(*head_ref == NULL)
new_node->min = new_data;
else
new_node->min = minimumOf(new_data,(*head_ref)->min);
new_node->next = *head_ref;
*head_ref = new_node;
}
int minimum(struct node *head){
return head->min;
}
int pop(struct node **head_ref){
int pop_data = (*head_ref)->data;
(*head_ref) = (*head_ref)->next;
return pop_data;
}
void printList(node *head){
while(head != NULL){
printf("%d->", head->data);
head = head->next;
}
printf("\b\n");
}
int main(){
struct node* a = NULL;
push(&a, 100);
push(&a, 24);
push(&a, 16);
push(&a, 19);
push(&a, 50);
printList(a);
printf("Minimum is:%d\n", minimum(a));
printf("Popped:%d\n",pop(&a));
printf("Minimum is:%d\n", minimum(a));
printf("Popped:%d\n",pop(&a));
printf("Minimum is:%d\n", minimum(a));
printf("Popped:%d\n",pop(&a));
printf("Minimum is:%d\n", minimum(a));
printf("Popped:%d\n",pop(&a));
printf("Minimum is:%d\n", minimum(a));
}
This will make you go wild - http://algods-cracker.blogspot.in/2011/09/design-data-structure-which-supports.html

How do I sort a list of integers using only one additional integer variable?

How to sort list of values using only one variable?
A solution in C:
#include <stdio.h>
int main()
{
int list[]={4,7,2,4,1,10,3};
int n; // the one int variable
startsort:
for (n=0; n< sizeof(list)/sizeof(int)-1; ++n)
if (list[n] > list[n+1]) {
list[n] ^= list[n+1];
list[n+1] ^= list[n];
list[n] ^= list[n+1];
goto startsort;
}
for (n=0; n< sizeof(list)/sizeof(int); ++n)
printf("%d\n",list[n]);
return 0;
}
Output is of course the same as for the Icon program.
I suspect I'm doing your homework for you, but hey it's an interesting challenge. Here's a solution in Icon:
procedure mysort(thelist)
local n # the one integer variable
every n := (1 to *thelist & 1 to *thelist-1) do
if thelist[n] > thelist[n+1] then thelist[n] :=: thelist[n+1]
return thelist
end
procedure main(args)
every write(!mysort([4,7,2,4,1,10,3]))
end
The output:
1
2
3
4
4
7
10
You could generate/write a lot of sorting-networks for each possible list size. Inside the sorting network you use a single variable for the swap operation.
I wouldn't recommend that you do this in software, but it is possible nevertheless.
Here's a sorting-routine for all n up to 4 in C
// define a compare and swap macro
#define order(a,b) if ((a)<(b)) { temp=(a); (a) = (b); (b) = temp; }
static void sort2 (int *data)
// sort-network for two numbers
{
int temp;
order (data[0], data[1]);
}
static void sort3 (int *data)
// sort-network for three numbers
{
int temp;
order (data[0], data[1]);
order (data[0], data[2]);
order (data[1], data[2]);
}
static void sort4 (int *data)
// sort-network for four numbers
{
int temp;
order (data[0], data[2]);
order (data[1], data[3]);
order (data[0], data[1]);
order (data[2], data[3]);
order (data[1], data[2]);
}
void sort (int *data, int n)
{
switch (n)
{
case 0:
case 1:
break;
case 2:
sort2 (data);
break;
case 3:
sort3 (data);
break;
case 4:
sort4 (data);
break;
default:
// Sorts for n>4 are left as an exercise for the reader
abort();
}
}
Obviously you need a sorting-network code for each possible N.
More info here:
http://en.wikipedia.org/wiki/Sorting_network
In java:
import java.util.Arrays;
/**
* Does a bubble sort without allocating extra memory
*
*/
public class Sort {
// Implements bubble sort very inefficiently for CPU but with minimal variable declarations
public static void sort(int[] array) {
int index=0;
while(true) {
next:
{
// Scan for correct sorting. Wasteful, but avoids using a boolean parameter
for (index=0;index<array.length-1;index++) {
if (array[index]>array[index+1]) break next;
}
// Array is now correctly sorted
return;
}
// Now swap. We don't need to rescan from the start
for (;index<array.length-1;index++) {
if (array[index]>array[index+1]) {
// use xor trick to avoid using an extra integer
array[index]^=array[index+1];
array[index+1]^=array[index];
array[index]^=array[index+1];
}
}
}
}
public static void main(final String argv[]) {
int[] array=new int[] {4,7,2,4,1,10,3};
sort(array);
System.out.println(Arrays.toString(array));
}
}
Actually, by using the trick proposed by Nils, you can eliminate even the one remaining int allocation - though of course that would add to the stack instead...
In ruby:
[1, 5, 3, 7, 4, 2].sort
You dont, it is already sorted. (as the question is vague, I shall assume variable is a synonym for an object)
If you have a list (1 5 3 7 4 2) and a variable v, you can exchange two values of the list, for example the 3 and the 7, by first assigning 3 to v, then assigning 7 to the place of 3, finally assigning the value of v to the original place of 7. After that, you can reuse v for the next exchange. In order to sort, you just need an algorithm that tells which values to exchange. You can look for a suitable algorithm for example at http://en.wikipedia.org/wiki/Sorting_algorithm .

Resources