Download Data Structures Part 2

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
Transcript
CSC215
Lecture
Data Structures
Part 2
Outline
● Linked Lists
● Binary Trees
● Stacks
● Queues
● Hash Tables
Binary Trees
● Binary Tree: dynamic data structure where each node has at most two children
● A binary search tree is a binary tree with ordering among its children
○
○
●
all elements in the left subtree are assumed to be ”less” than the root element
and all elements in the right subtree are assumed to be "greater" than the root element
Example:
struct tnode{
void* data; /∗ payload ∗/
struct tnode∗ left;
struct tnode∗ right;
};
struct tree{
struct tnode root;
}
Binary Trees
● The operation on trees can be framed as recursive operations.
○
●
Traversal (printing, searching):
■ pre-order: root, left subtree, right subtree
■ inorder: left subtree, root, right subtree
■ post-order: left subtree, right subtree, root
Add node:
struct tnode∗ addnode(struct tnode∗ root, int data){
if (root==NULL){ /∗ termination condition ∗/
/∗ allocate node and return new root ∗/
}
else if (data < root−>data) /∗ recursive call ∗/
return addnode(root−>left, data);
else
return addnode(root−>right, data);
}
Stack
● A structure that stores data with restricted insertion and removal:
○
○
○
●
insertion occurs from the top exclusively: push
removal occurs from the top exclusively: pop
For this reason, a stack is referred to as a last-in, first-out (LIFO) data structure.
struct Stack {
int data; /* define data as an int */
struct Stack *nextPtr; /* stack pointer */
}; /* end structure Stack */
●
●
●
typedef struct Stack Stack;
Stack* new_stack(int size);
void* pop(Stack** q);
void push(Stack** q, void* data);
may provide void*
top(void);
to read last (top) element without removing it.
Stack could be implemented as an Array or as Linked List.
Stack as a Linked List
● Stores in a linked list (dynamic allocation)
● “Top” is now at front of linked list (no need to track)
/* Insert a node at the stack top */
void push( Stack**topPtr, int info ) {
Stack * newPtr; /* pointer to new node */
newPtr = (Stack*) malloc( sizeof( Stack) );
/* Return 1 if the stack is empty, 0 otherwise */
int isEmpty( Stack * topPtr ) {
return (topPtr == NULL);
/* insert the node at stack top */
if ( newPtr != NULL ) {
newPtr->data = info;
newPtr->nextPtr = *topPtr;
*topPtr = newPtr;
} /* end if */
else {
printf( "%d not inserted. No memory
available.\n", info );
}/*end else*/
} /* end function push */
In the main :
Stack * stackPtr = NULL; /* points to stack top */
push(&stackPtr, 3);
} /* end function isEmpty */
Queue
● Opposite of stack:
Queue nodes are removed only from the head of the queue and are inserted only at
the tail of the queue. For this reason, a queue is referred to as a first-in, first-out
(FIFO) data structure.
The insert and remove operations are known as enqueue and dequeue.
○
○
○
first in: enqueue
first out: dequeue
Read and write from opposite ends of list
● Important for:
○
○
networking (Rx packet queues)
:
● Imposes an ordering on elements.
● Queue also could be implemented as an Array or as Linked List.
Queue as a Linked List
● Stores in a linked list (dynamic allocation)
● typedef struct Queue Queue;
● /* function prototypes */
struct Queue {
char data;
struct Queue *nextPtr;
};
void printQueue( Queue *currentPtr );
int isEmpty( Queue * headPtr );
char dequeue( Queue ** headPtr, Queue ** tailPtr );
void enqueue( Queue **headPtr, Queue **tailPtr, char value );
Queue * headPtr = NULL; /* initialize headPtr */
Queue * tailPtr = NULL; /* initialize tailPtr */
enqueue and isEmpty
void enqueue( Queue **headPtr, Queue **tailPtr, char
value )
{ Queue * newPtr; /* pointer to new node */
newPtr = (Queue*) malloc( sizeof( QueueNode ) );
if ( newPtr != NULL ) {
newPtr->data = value;
newPtr->nextPtr = NULL;
/* if empty, insert node at head */
if ( isEmpty( * headPtr ) ) {
*headPtr = newPtr;
} /* end if */
else {
(*tailPtr) ->nextPtr = newPtr;
} /* end else */
*tailPtr = newPtr;
} /* end if */
else {
printf( "%c not inserted. No memory available.\n", value
);
} /* end else */
}
/* Return 1 if the list is empty, 0
otherwise */
int isEmpty( Queue * headPtr )
{
return (headPtr == NULL);
} /* end function isEmpty */
Hash Table
● Hash tables (hashmaps) an efficient data structure for storing dynamic data.
● Hash tables are good for doing a quick search on things.
● commonly implemented as an array of linked lists (hash tables with chaining).
● Each data item is associated with a key that determines its location.
○
○
○
○
Hash functions are used to generate an evenly distributed hash value which maps them down to
array indices.
A hash collision is said to occur when two items have the same hash value.
One way to avoid collision: Items with the same hash keys are chained
Retrieving an item is O(1) operation.
● Hash function: map its input into a finite range: hash value, hash code.
○
Hash function types:
■ Division type
■ Multiplication type: The most commonly used hash-function.
■ Other ways to avoid collision: linear probing, double hashing.
● Applications of hash tables: Caches, cryptography, implementing passwords for
system with multiple users, internet search engines, telephone book database, ..etc
Chained Hash Table Example