Skip to content

Commit

Permalink
Merge pull request #33 from tekinozbek/master
Browse files Browse the repository at this point in the history
BinarySearchTree implemented...
  • Loading branch information
patmorin committed Jun 6, 2016
2 parents 019e2fc + c915e59 commit da33891
Show file tree
Hide file tree
Showing 6 changed files with 448 additions and 134 deletions.
2 changes: 1 addition & 1 deletion c/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ INSDIR = /usr/lib

OBJ = arraystack.o arrayqueue.o arraydeque.o dualarraydeque.o \
rootisharraystack.o sllist.o dllist.o selist.o skiplistsset.o skiplist.o \
chainedhashtable.o
chainedhashtable.o binarysearchtree.o

lib: $(OBJ)
$(SHARED_LIB)
Expand Down
259 changes: 130 additions & 129 deletions c/README.md
Original file line number Diff line number Diff line change
@@ -1,129 +1,130 @@
## Open Data Structures in C

This is an implementation of [Open Data Structures](http://opendatastructures.org)
in C. It is written in ANSI C (C89) to maximize compatibility with other
compilers.

#### Implemented data structures

More information on the data structures (implementation details, running times,
etc.) can be found in [the book](http://opendatastructures.org).

* [ArrayStack](include/arraystack.h) (equivalent to FastArrayStack in the book)
* [ArrayQueue](include/arrayqueue.h)
* [ArrayDeque](include/arraydeque.h)
* [DualArrayDeque](include/dualarraydeque.h)
* [RootishArrayStack](include/rootisharraystack.h)
* [SLList](include/sllist.h)
* [DLList](include/dllist.h)
* [SEList](include/selist.h)
* [SkiplistSSet](include/skiplistsset.h)
* [SkiplistList](include/skiplist.h)
* [ChainedHashTable](include/chainedhashtable.h)

#### How to use the library

If you have [gcc](https://gcc.gnu.org/onlinedocs/gcc/) installed, simply run
either `make` to compile the shared object file or `make install` to compile and
install the library (by default, it is moved to `/usr/lib/libodsc.so`).
After that, you can append `-lodsc` to your compiler arguments to link your code
with the library.

If you don't have gcc, you can modify the Makefile for your compiler (with
[clang](http://clang.llvm.org), you only need to change the compiler variable,
everything else should work the same). Or, compile the sources in `src/` with
the headers in `include/`.

The [include](include/) directory contains the headers you will need to include
in your program. Detailed information on the functions and their arguments can
be found in the header files.

This library follows a general structure: `[data structure]_[function]`. For
example, the function to initialize an ArrayStack is `arraystack_init`.

##### Example

```c
#include <stdio.h>
#include <arraystack.h>

int main() {

int i;

arraystack_t stack;

/* initialize the struct with the size of the elements you want to store
* inside. this will allocate memory for the backing array. */
arraystack_init(&stack, sizeof(int));

for (i = 0; i < 10; i++)
arraystack_push(&stack, &i);

while (stack.length > 0) {
arraystack_pop(&stack, &i);
printf("popped: %d\n", i);
}

/* make sure to call dispose when you're done, to avoid memory leaks */
arraystack_dispose(&stack);

return 0;
}
```

#### Uniform iteration

Different data structures can require different methods to efficiently iterate
over them. For example, it is possible to iterate through an ArrayStack using
`_get()` but using the same method on a DLList would be costly. Uniform
iterators provide a simple way of iterating over these data structures. Best to
consider them invalidated if you do any kind of insertion/removal on the data
structure you are iterating on. Iterators come with overhead since they have to
maintain state and keep function pointers.

If an iterator is implemented for a data structure, it can be initialized
through `_iterator()`. Iterators have three functions:

* `next(iterator_t *)`: Advances to the next element and returns 1, if
available. Otherwise, returns 0. If iterating in reverse, this will advance to
the previous element (**not all data structures can be iterated in reverse
order**, check the documentation for `_iterator()`).
* `elem(iterator_t *)`: Returns a pointer to the element *in* the data structure
(i.e. not a copy). Be careful not to exceed the bounds of this pointer (which is
`elem_size` bytes).
* `dispose(iterator_t *)`: Releases allocated memory.

##### Example

```c
#include <stdio.h>
#include <iterator.h>
#include <arraystack.h>

int main() {

int i;

arraystack_t stack;
arraystack_init(&stack, sizeof(int));

for (i = 0; i < 10; i++)
arraystack_push(&stack, &i);

/* make an iterator for stack[1,4] */
iterator_t it;
arraystack_iterator(&stack, &it, 1, 4);

while (it.next(&it))
printf("%d\n", *(int *)it.elem(&it));

/* iterators allocate memory for state, which must be released. */
it.dispose(&it);

arraystack_dispose(&stack);

return 0;
}
```
## Open Data Structures in C

This is an implementation of [Open Data Structures](http://opendatastructures.org)
in C. It is written in ANSI C (C89) to maximize compatibility with other
compilers.

#### Implemented data structures

More information on the data structures (implementation details, running times,
etc.) can be found in [the book](http://opendatastructures.org).

* [ArrayStack](include/arraystack.h) (equivalent to FastArrayStack in the book)
* [ArrayQueue](include/arrayqueue.h)
* [ArrayDeque](include/arraydeque.h)
* [DualArrayDeque](include/dualarraydeque.h)
* [RootishArrayStack](include/rootisharraystack.h)
* [SLList](include/sllist.h)
* [DLList](include/dllist.h)
* [SEList](include/selist.h)
* [SkiplistSSet](include/skiplistsset.h)
* [SkiplistList](include/skiplist.h)
* [ChainedHashTable](include/chainedhashtable.h)
* [BinarySearchTree](include/binarysearchtree.h)

#### How to use the library

If you have [gcc](https://gcc.gnu.org/onlinedocs/gcc/) installed, simply run
either `make` to compile the shared object file or `make install` to compile and
install the library (by default, it is moved to `/usr/lib/libodsc.so`).
After that, you can append `-lodsc` to your compiler arguments to link your code
with the library.

If you don't have gcc, you can modify the Makefile for your compiler (with
[clang](http://clang.llvm.org), you only need to change the compiler variable,
everything else should work the same). Or, compile the sources in `src/` with
the headers in `include/`.

The [include](include/) directory contains the headers you will need to include
in your program. Detailed information on the functions and their arguments can
be found in the header files.

This library follows a general structure: `[data structure]_[function]`. For
example, the function to initialize an ArrayStack is `arraystack_init`.

##### Example

```c
#include <stdio.h>
#include <arraystack.h>

int main() {

int i;

arraystack_t stack;

/* initialize the struct with the size of the elements you want to store
* inside. this will allocate memory for the backing array. */
arraystack_init(&stack, sizeof(int));

for (i = 0; i < 10; i++)
arraystack_push(&stack, &i);

while (stack.length > 0) {

arraystack_pop(&stack, &i);
printf("popped: %d\n", i);
}

/* make sure to call dispose when you're done, to avoid memory leaks */
arraystack_dispose(&stack);

return 0;
}
```

#### Uniform iteration

Different data structures can require different methods to efficiently iterate
over them. For example, it is possible to iterate through an ArrayStack using
`_get()` but using the same method on a DLList would be costly. Uniform
iterators provide a simple way of iterating over these data structures. Best to
consider them invalidated if you do any kind of insertion/removal on the data
structure you are iterating on. Iterators come with overhead since they have to
maintain state and keep function pointers.

If an iterator is implemented for a data structure, it can be initialized
through `_iterator()`. Iterators have three functions:

* `next(iterator_t *)`: Advances to the next element and returns 1, if
available. Otherwise, returns 0. If iterating in reverse, this will advance to
the previous element (**not all data structures can be iterated in reverse
order**, check the documentation for `_iterator()`).
* `elem(iterator_t *)`: Returns a pointer to the element *in* the data structure
(i.e. not a copy). Be careful not to exceed the bounds of this pointer (which is
`elem_size` bytes).
* `dispose(iterator_t *)`: Releases allocated memory.

##### Example

```c
#include <stdio.h>
#include <iterator.h>
#include <arraystack.h>

int main() {

int i;

arraystack_t stack;
arraystack_init(&stack, sizeof(int));

for (i = 0; i < 10; i++)
arraystack_push(&stack, &i);

/* make an iterator for stack[1,4] */
iterator_t it;
arraystack_iterator(&stack, &it, 1, 4);

while (it.next(&it))
printf("%d\n", *(int *)it.elem(&it));

/* iterators allocate memory for state, which must be released. */
it.dispose(&it);

arraystack_dispose(&stack);

return 0;
}
```
110 changes: 110 additions & 0 deletions c/include/binarysearchtree.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*******************************************************************************
* File : binarysearchtree.h
* Author(s) : Tekin Ozbek <tekin@tekinozbek.com>
******************************************************************************/

#ifndef ODS_BINARYSEARCHTREE_H_
#define ODS_BINARYSEARCHTREE_H_

#include <stdlib.h>

typedef struct btnode_t {

void* data;

struct btnode_t* parent;
struct btnode_t* left;
struct btnode_t* right;

} btnode_t;

typedef struct {

btnode_t* root;

size_t elem_size;
size_t length;

int (*cmp)(void *, void *);

} binarysearchtree_t;

/* FUNCTION
* binarysearchtree_add
*
* DESCRIPTION
* Adds an element to the tree.
*
* PARAMETERS
* tree A valid pointer to an initialized binarysearchtree_t struct.
* elem The element that will be copied into the tree.
*/
extern void binarysearchtree_add(binarysearchtree_t* tree,
void* elem);

/* FUNCTION
* binarysearchtree_dispose
*
* DESCRIPTION
* Frees allocated memory. Once disposed, a binarysearchtree_t structure
* should be re-initialized before use.
*
* PARAMETERS
* tree A valid pointer to an initialized binarysearchtree_t struct.
*/
void binarysearchtree_dispose(binarysearchtree_t* tree);

/* FUNCTION
* binarysearchtree_find
*
* DESCRIPTION
* Finds an element in the tree.
*
* PARAMETERS
* tree A valid pointer to an initialized binarysearchtree_t struct.
* search The element that is being searched.
*
* RETURN VALUES
* Returns a non-zero value if the element that was being searched is
* found in the tree, zero otherwise.
*/
extern int binarysearchtree_find(binarysearchtree_t* tree,
void* search);

/* FUNCTION
* binarysearchtree_init
*
* DESCRIPTION
* Initializes the binarysearchtree_t struct.
*
* PARAMETERS
* tree A valid pointer to a binarysearchtree_t struct.
* elem_size Size of the type that will be inserted in the tree.
* comparator Pointer to a comparator function that takes two void*
* parameters and returns an int. The function must return
* less than zero if the first parameter comes before the
* second parameter and greater than zero if vice versa.
* The function must return zero if arguments are equal.
*/
extern void binarysearchtree_init(binarysearchtree_t* tree,
size_t elem_size,
int(*comparator)(void *, void *));

/* FUNCTION
* binarysearchtree_remove
*
* DESCRIPTION
* Removes an element from the tree.
*
* PARAMETERS
* tree A valid pointer to an initialized binarysearchtree_t struct.
* search The element that will be removed from the tree.
*
* RETURN VALUES
* Returns a non-zero value if the element was found and removed; returns
* zero if the element was not found.
*/
extern int binarysearchtree_remove(binarysearchtree_t* tree,
void* elem);

#endif
3 changes: 0 additions & 3 deletions c/include/chainedhashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ extern int chainedhashtable_find(chainedhashtable_t* table,
* random Pointer to a random function that takes no parameters and
* returns an int value. If null, the default rand() from the
* standard library is used.
*
* RETURN VALUES
* Returns 1 if the element was found, 0 otherwise.
*/
extern void chainedhashtable_init(chainedhashtable_t *table,
size_t elem_size,
Expand Down
Loading

0 comments on commit da33891

Please sign in to comment.