About MeCurriculumLicensePortfolioProjectsPublicationsBD-blog

Posts Tagged ‘data structures’

Time for two new C programs! At the DSA course I learned something about Hash Tables and collision resolutions.
I just implemented insert/search/print operations.

The first source code is an implementation of a Hash Map with open addressing (linear probing) as collision resolution method.
The following are the interesting functions of the program. As always, take a look at the source code for comments:

// hashMapLinear[] is the hash map
void linearProbingInsert(int value){
    int probe = hash(value);
    while (hashMapLinear[probe]!=0){                            
        probe = fmod((probe+1),SIZE_HASH_MAP);
    }
    hashMapLinear[probe] = value;
}

int linearProbingSearch(int value){
    int probe = hash(value);  
    int i;
    for(i=0;i<size_hash_map ;i++){    
        if(hashMapLinear[probe]==value)
            return TRUE;                            
        probe = fmod((probe+1),SIZE_HASH_MAP);              
    }
    return FALSE;                                          
}
 

Download: hash-map-linear-probing.c

The second program is an implementation of a Hash Map with chaining as collision resolution method.
Interesting functions:

// t_hashTableNode is a struct that is created as single linked list
void chainedHashInsert(int value){
    int probe = hash(value);                        
    if(hashMapChained[probe] == NULL){          
        hashMapChained[probe] = malloc(sizeof(t_hashTableNode));
        hashMapChained[probe]->value = value;
        hashMapChained[probe]->next = NULL;
    }else{
        t_hashTableNode *hashTableNode = hashMapChained[probe];
        while(hashTableNode->next!=NULL){
            hashTableNode = hashTableNode->next;
        }
        hashTableNode->next = malloc(sizeof(t_hashTableNode));
        hashTableNode->next->value = value;
        hashTableNode->next->next = NULL;
    }
}

int chainedHashSearch(int value){
    t_hashTableNode *hashTableNode = hashMapChained[hash(value)];
    while(hashTableNode!=NULL){
        if(hashTableNode->value==value){
            return TRUE;
        }
        hashTableNode = hashTableNode->next;
    }
    return FALSE;
}
 

Download: hash-map-chaining.c

 
 

21
Apr

image for post title  BD-shell

BD-shell (a.k.a. bdsh) is a tiny Unix shell written in C. It's a project required for the Operating System Course at my University.
It is written using a clean coding style, following xP coding standard philosophy.
Version 1.0 is the release that satisfies all the course requirements!

Quick Jump:
Features
Download
License

Features

Cool Features

  • Lightweight
  • Implements real Job Control
  • Clear and understandable code, ideal for Academic (and personal) studies
  • Makes use of various system calls, signals, signal handlers, user input handling, data structures implementation
  • Free Software!

Cool Features NOT present (but may be in future)

  • No command history present
  • No command/filename auto completion
  • No wildcars
  • No command piping, just a single command can be launched at a time
  • Put everything else here.
These are the requirements asked by the teaching professor. The complete project description page is located at http://www.inf.unibz.it/~david/os/project.html
The shell must be able to do the following:

  1. to read commands from standard input and execute them in a loop until a
    built-in command exit is issued (we call these processes the foreground processes; there is always at most one of these at any particular time);
  2. be able to redirect the standard input and output of commands by prefixing them with built-in commands in file and out file;
  3. be able to terminate (involuntarily) the foreground process when user presses ^C and return back to the mini-shell;
  4. be able to interrupt the foreground process temporarily, when user presses ^Z, returning to the mini-shell;
  5. be able to execute any number of processes in background (i.e., in parallel with the foreground process), including in particular, the ability to start another process while a process has been temporarily suspended;
  6. inform the user when the background process finishes or is
    waiting for an input from the terminal;
  7. be able to inform the user what commands are executing in the background by issuing the built-in command jobs, this should include information about the state of the process (i.e., suspended, background, waiting for input, etc.) and about what file(s) is the background process using for standard input and output);
  8. be able to terminate involuntarily a background processes by issuing the built-in command kill job-number.
  9. to be able to resume a process or to make a background process into the foreground process (i.e., the one that currently interacts with the terminal) by issuing the fg job-number command.

Download:

  • 2008-09-14 - version 1.0.0.
    • fixed synchronization bug in putJobBackground() that made not notify background processes requesting input (in some situations)

    Known Bugs:

    • Lots of! I consider bdsh-1.0.0 stable because it covers ALL requirements of the course and does them whell on various Unix systems. So it works, but commands like "in non_existent_file cat" won't work and will crash it!

    What will be next?

    • I don't know. I may consider a 1.0.1 release to fix future bugs. I may also think to add cool features to make the shell complete. I hope I will have the time for it. You can also do it by yourself and send me the code
  • 2008-09-13 - version 1.0.0 Release Candidate 2.
    Changes from beta 1 / release candidate 1

    • removed gcc O3 flag from makefile
    • lots of bugs fixed in functions operating on the list of jobs
    • improvements in launchJob() when dealing with background commands
    • bug in putJobBackground() that made the shell crash has been fixed
    • killJob() now sends a SIGKILL
    • bugs fixed in signalHandler_child()
    • Code formatted using astyle (linux style)
    • A couple of variables renamed
    • Various usleep() removed

    Known Bugs:

    • So many =) This is a shell made for Academic purposes, not for production use!
  • 2008-07-30 - version 1.0.0 beta1.
    Characteristics:

    • First beta release of the final version
    • Every requirement has been covered
    • Real Job-Control implemented
    • About every function of bdsh.c has been rewritten
    • New source directory layout, very clean
    • Some documentation and makefile
    • IMPORTANT! this has to be considered a bug hunting release! Please report me any bugs
  • 2008-06-05 - version 0.7.1, corrects the linked list bug of version 0.7.0
  • 2008-05-09 - version 0.7.0.
    UPDATE 2008-06-05: there is a bug in the list handling, the shell crashes when using the standard input redirection. Please download version 0.7.1, which corrects the problem.
    Characteristics:
    • Cleaner code!
    • Lots of bugs fixed!
    • reads commands from standard input and executes them in a loop until a built-in command exit is issued
    • redirects STDIN and STDOUT of commands by prefixing them with built-in commands in file and out file
    • terminates (involuntarily) the foreground process when user presses ^C and return back to the shell
    • executes any number of processes in background (i.e., in parallel with the foreground process)
    • informs the user when the background process finishes
    • informs the user what commands are executing in the background by issuing the built-in command jobs
    • terminates involuntarily a background processes by issuing the built-in command kill job-number.
  • Due to a lots of compatibility issues with Gnu/Linux (the shell has been developed under Mac Os X), the final released has been delayed to mid-September. Sorry for this, I encountered so many problems the day before project presentation, that I decided to present it during the next exam session. I switched back to Gnu/Linux, too :)
  • Final release is scheduled on 2008-06-26, as the project deadline is 2008-06-25. The release will
    satisfy all the requirements, and as addition:

    • Execution system totally rewritten (e.g. one single short function that handles everything)
    • A Job Control will be implemented
    • Processes in foreground will really be in foreground, there are a lot of things that we did not learn during the course, like tcsetpgrp()
    • Some functions in utils.h will be deleted and optimized
    • Cleaner and clearer code!

  • 2008-04-21 - version 0.0.1
    Characteristics:
    • Modular code, divided in 3 files: bdsh.c, utils.h, headers.h
    • Clean user input from a char buffer to an array of strings
    • Built-in commands: exit (exits from the shell), cd (changes directory), in <filename> command (redirects STDIN of command from <filename>), out <filename> command (redirects STDOUT of command to <filename>)
    • Makes use of fork() to read commands from standard input and execute them

License:

BD-shell is released under The Gnu GPL version 3! This is different from the license of the contents of the blog

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http ://www.gnu.org/licenses/>>.

 
 

As assignment for Data Structures and Algorithms course, we had to work with a modified version of the quicksort algorithm. It came obvious that for modifying a qsort you need to implement it :-)

It is difficult to find a clear quicksort algorithm implemented, so I wrote it.

Here is the generic C implementation of the Quicksort Algorithm, which sorts an array in place, following the Divide And Conquer design.

Download: quicksort qsort in C language

Interesting methods (look at the source code for comments):

int partition( int A[], int left, int right) {
        int pivot;
        pivot = A[right];                                                                      
        while(1){
                while( A[right] > pivot){
                        right--;
                }
                while( A[left] < pivot){       
                        left++;                                
                }
                if( left < right ){                                                            
                        swap(A,left,right);
                }else{
                        return left;                                   
                }
        }
}

void quicksort( int A[], int left, int right){
        int m;
        if( left < right ) {                           
                m = partition( A, left, right);        
                quicksort( A, left, m-1);              
                quicksort( A, m+1, right);
        }       
}
 

As you see, there is nothing optimized in this implementation. It just looks elegant and easy to be understood.
If you would like to have a more optimized version of this algorithm, take a look at this one.

 
 

This is what happens if you give to two IT students a stressful assignment of "Data Structures
and Algorithms", 48 hours of their meaningful life, the loss of a saturday night, and the 6th
floor of the most recent building of the Free University of Bolzano:

IT Guys habitat in unibz

..they begin to behave like real IT guys..and to build their ideal working habitat..

Habitat of two IT guys Data Structures and Algorithms Assignment DSA

..and to worship fake idols..

Forno Damiani Free University Bolzano

 
 

UPDATE 17:19: it seems that the program I implemented today uses a kind of Bubble Sort algorithm, give it a try, it's quite interesting!

After 3 long days studying C, I think I've assimilated a good knowledge base for the incoming semester.
So there is a tiny C program that sorts the elements of a given integer array, using pointers:

Download the source code (well commented)

#include <stdio.h>
void sortArray(int *firstElement, int *lastElement);
void swapArrayElements(int *firstElement, int *secondElement);
void printArray(int array[], int arraySize);

void sortArray(int *firstElement, int *lastElement){
        int *currentElement = firstElement;
        while (firstElement != lastElement){
                while(currentElement != lastElement){
                        if(*currentElement < *firstElement){
                                swapArrayElements(currentElement,firstElement);
                        }
                        currentElement++;
                }
                firstElement++;
                currentElement = firstElement;
        }
}

void swapArrayElements(int *firstElement, int *secondElement){
        int tmp;
        tmp = *firstElement;
        *firstElement = *secondElement;
        *secondElement = tmp;
}

void printArray(int array[], int arraySize){
        int counter = 0;
        while(counter<arraySize){
                printf("%d\n",array[counter]);
                counter++;
        }
}

int main (int argc, char *argv[]){
        int array[] = {2929393,1,23239,-66,15,4,3,0,112,45,3,1000,19};
        int arraySize = sizeof(array)/sizeof(array[0]);
        int *firstElement = &array[0];
        int *lastElement = firstElement + arraySize;
        printf("-------------------------------------------------\n");
        printf("Elements of the array:\n");
        printf("-------------------------------------------------\n");
        printArray(array,arraySize);
        printf("-------------------------------------------------\n");
        sortArray(firstElement,lastElement);
        printf("Elements sorted:\n");
        printf("-------------------------------------------------\n");
        printArray(array,arraySize);
        printf("-------------------------------------------------\n");
}

 

A better program should ask the user to input the array elements, and a better algorithm should not scan every array element n times, where n is the number of the elements.
But I wrote it just for fun and for learning C pointers. I will learn to do better in the Data Structures and Algorithms course in the next semester ;)