Algorithms and Data Structures Objectives: To review the fundamental algorithms and data structures that are commonly used in programs. To see how to use.

Slides:



Advertisements
Similar presentations
Pointers.
Advertisements

Computer Programming for Engineering Applications ECE 175 Intro to Programming.
1 Symbol Tables Chapter Sedgewick. 2 Symbol Tables Searching Searching is a fundamental element of many computational tasks looking up a name.
Hashing as a Dictionary Implementation
Senem Kumova Metin Spring2009 BINARY TREES && TREE TRAVERSALS Chapter 10 in A Book on C.
1 abstract containers hierarchical (1 to many) graph (many to many) first ith last sequence/linear (1 to 1) set.
Linked Lists... An introduction to creating dynamic data structures.
Searching Kruse and Ryba Ch and 9.6. Problem: Search We are given a list of records. Each record has an associated key. Give efficient algorithm.
TTIT33 Algorithms and Optimization – Lecture 5 Algorithms Jan Maluszynski - HT TTIT33 – Algorithms and optimization Lecture 5 Algorithms ADT Map,
Chapter 12 C Data Structures Acknowledgment The notes are adapted from those provided by Deitel & Associates, Inc. and Pearson Education Inc.
COMP 171 Data Structures and Algorithms Tutorial 10 Hash Tables.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved. Chapter 12 – Data Structures Outline 12.1Introduction.
Lecture 10: Search Structures and Hashing
1 abstract containers hierarchical (1 to many) graph (many to many) first ith last sequence/linear (1 to 1) set.
Hashing General idea: Get a large array
Introducing Hashing Chapter 21 Copyright ©2012 by Pearson Education, Inc. All rights reserved.
CSCE 3110 Data Structures & Algorithm Analysis Binary Search Trees Reading: Chap. 4 (4.3) Weiss.
Chapter 12 Data Structure Associate Prof. Yuh-Shyan Chen Dept. of Computer Science and Information Engineering National Chung-Cheng University.
FEN 2012UCN Technology - Computer Science 1 Data Structures and Collections Principles revisited.NET: –Two libraries: System.Collections System.Collections.Generics.
1 Hash Tables  a hash table is an array of size Tsize  has index positions 0.. Tsize-1  two types of hash tables  open hash table  array element type.
1 Data Structures Lists and Trees. 2 Real-Life Computational Problems All about organizing data! –What shape the data should have to solve your problem.
Implementation of Linked List For more notes and topics visit: eITnotes.com.
Symbol Tables Symbol tables are used by compilers to keep track of information about variables functions class names type names temporary variables etc.
 2007 Pearson Education, Inc. All rights reserved C Data Structures.
CHAPTER 09 Compiled by: Dr. Mohammad Omar Alhawarat Sorting & Searching.
Introduction to Data Structures Systems Programming.
Searching: Binary Trees and Hash Tables CHAPTER 12 6/4/15 Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education,
Algorithms and Data Structures* Objective: To review the fundamental algorithms and data structures that are commonly used in programs. To see how to use.
17. ADVANCED USES OF POINTERS. Dynamic Storage Allocation Many programs require dynamic storage allocation: the ability to allocate storage as needed.
Final Review Dr. Bernard Chen Ph.D. University of Central Arkansas Spring 2010.
IS 2610: Data Structures Searching March 29, 2004.
C++ Programming: From Problem Analysis to Program Design, Second Edition Chapter 19: Searching and Sorting.
TECH Computer Science Dynamic Sets and Searching Analysis Technique  Amortized Analysis // average cost of each operation in the worst case Dynamic Sets.
Generic Programming Using the C++ Standard Template Library.
1 Hash table. 2 A basic problem We have to store some records and perform the following:  add new record  delete record  search a record by key Find.
1 CSE 1342 Programming Concepts Lists. 2 Basic Terminology A list is a finite sequence of zero or more elements. –For example, (1,3,5,7) is a list of.
C What you Know* Objective: To introduce some of the features of C. This assumes that you are familiar with C++ or java and concentrates on the features.
CSC 211 Data Structures Lecture 13
© M. Gross, ETH Zürich, 2014 Informatik I für D-MAVT (FS 2014) Exercise 12 – Data Structures – Trees Sorting Algorithms.
Hashing Hashing is another method for sorting and searching data.
Introduction to Data Structures Systems Programming Concepts.
Data Structure & Algorithm
1 Hashing - Introduction Dictionary = a dynamic set that supports the operations INSERT, DELETE, SEARCH Dictionary = a dynamic set that supports the operations.
Hash Tables CSIT 402 Data Structures II. Hashing Goal Perform inserts, deletes, and finds in constant average time Topics Hash table, hash function, collisions.
Java Methods Big-O Analysis of Algorithms Object-Oriented Programming
Hash Tables. 2 Exercise 2 /* Exercise 1 */ void mystery(int n) { int i, j, k; for (i = 1; i
Hash Table March COP 3502, UCF 1. Outline Hash Table: – Motivation – Direct Access Table – Hash Table Solutions for Collision Problem: – Open.
Hashtables. An Abstract data type that supports the following operations: –Insert –Find –Remove Search trees can be used for the same operations but require.
Data Structures. Abstract Data Type A collection of related data is known as an abstract data type (ADT) Data Structure = ADT + Collection of functions.
HEAPS. Review: what are the requirements of the abstract data type: priority queue? Quick removal of item with highest priority (highest or lowest key.
FALL 2005CENG 213 Data Structures1 Priority Queues (Heaps) Reference: Chapter 7.
Symbol Tables Computing 2 COMP s1. S YMBOL T ABLES Searching: like sorting, searching is a fundamental element of many computational tasks data.
Week 15 – Wednesday.  What did we talk about last time?  Review up to Exam 1.
1 Principles revisited.NET: Two libraries: System.Collections System.Collections.Generics Data Structures and Collections.
MORE POINTERS Plus: Memory Allocation Heap versus Stack.
1 Linked List. 2 List A list refers to a sequence of data items  Example: An array The array index is used for accessing and manipulation of array elements.
1 the BSTree class  BSTreeNode has same structure as binary tree nodes  elements stored in a BSTree are a key- value pair  must be a class (or a struct)
C Tutorial - Pointers CS 537 – Introduction to Operating Systems.
Chapter 12 – Data Structures
CSCE 3110 Data Structures & Algorithm Analysis
5.13 Recursion Recursive functions Functions that call themselves
Hashing CSE 2011 Winter July 2018.
abstract containers sequence/linear (1 to 1) hierarchical (1 to many)
Tree data structure.
Map interface Empty() - return true if the map is empty; else return false Size() - return the number of elements in the map Find(key) - if there is an.
Hash Tables in C James Goerke.
Tree data structure.
Hash Tables: A basic O(1)verview
DATA STRUCTURE.
Comp 208 Computers in Engineering Yi Lin Fall, 2005
Presentation transcript:

Algorithms and Data Structures Objectives: To review the fundamental algorithms and data structures that are commonly used in programs. To see how to use and implement these algorithms and data structures in different languages and to see what language and library support exists for them.

Topics Arrays and Vectors Lists Linear/Binary Search Quicksort Hash Tables - Dictionaries C, C++, Java, Perl

Arrays Sequence of items Indexable (can refer to any element immediately, by its index number) (Conceptually) contiguous chunks of memory

Arrays Access: constant-time (θ(1)) Searching: Sorted array - θ(lg(n)) Unsorted - θ(n) Inserting/removing Unordered - θ(1)  (Add to end, or swap last guy w/deleted guy) Ordered - θ(n)  Need to make (or fill in) a hole, move n/2 elements (on average) to maintain relative order

Resizing Arrays If the number of elements in an array is not known ahead of time it may be necessary to resize the array. Involves dynamic memory allocation and copying To minimize the cost it is best to resize in chunks (some factor of its current size)

Libraries - Arrays Arrays (lists) in Perl, Bash, Python, Awk, resize automatically, as do C++ vectors, and the Array in Java This does not mean that it is free. Depending on the task, what goes on underneath the hood may be important We shall create our own machinery in C

Some C memory things… void* malloc(int n) – allocates n contiguous bytes from heap, returns address of first byte ( NULL if it failed) free( void* p ) – returns memory addressed by p to the heap (does nothing to p itself) void* memmove( void* d, void* s, size_t n ) – moves n bytes from s to (possibly overlaping region at) d void* memcpy( void* d, void* s, size_t n ) – copies n bytes from s to (non-overlaping region at) d sizeof() – actually an operator, returns size, in bytes, of given object or type void* realloc( void* src, size_t n ) – attempts to resize array for you, and copy the stuff over. Returns ptr to new location (might be the same), NULL if it fails.

Growing Arrays in C enum { INIT_SIZE=1, GROW_FACTOR=2 }; int curr_size = INIT_SIZE; int nr_elems = 0; /* # of useful elements */ int *a = (int*)malloc( INIT_SIZE * sizeof( int )); … /* some stuff here */ /* attempt to insert 24 */ if( nr_elems >= curr_size ) { /* need to grow */ int *t = realloc( a, curr_size*GROW_FACTOR*sizeof( int )) if( t != NULL ) { /* success! */ curr_size *= GROW_FACTOR; a = t; a[nr_elems++] = 24; } else /* FAILURE! */ }

Lists A sequence of elements Not indexable (immediately) Space is allocate for each new element and consecutive elements are linked together with a pointer. Note, though, that the middle can be modified in constant time. data 1data 2data 3 NULL data 4 head

Lists Access (same as searching) – linear, θ(n) Modifying anywhere – constant time, θ(1) θ(1) time to insert at front, θ(n) to append unless pointer to last element kept

Lists in Python The list-type in Python is really an array (I think. Somebody experiment? How would you?). We can make a linked-list in a very LISP way; build it out of simple pairs 1 st element – the data at that node 2 nd element – the rest of the list

Lists in Python L = [] # add 24 to front L = [ 24, L ] print L # add 3 to the front L = [ 3, L ] print L Would output: [ 24, [] ] [ 3, [ 24, [] ]]

Lists in Python – append to end append the number 86: t = L # start at beginning # get hands on last cell while t != [] : t = t[1] # move to next "cell", or node t.extend( [ 86, [] ] )

Lists in Python – searching def search( L, t ) : """Return cell of L that contains t, None if not found""" while L != [] : if L[0] == t : return L L = L[1] # move to next "cell" return None # didn't find it

Apply function to elements def apply( l, fn ) : while l != [] : fn( l ) l = l[1] fn is any function that takes a single cell, does something

Lists in Python – apply Print list: def printCell( cell ) : print cell[0], apply( L, printCell ) Add 2 to each element in list: def add2( cell ) : cell[0] += 2 apply( L, add2 )

Lists in C typedef struct sNode sNode; struct sNode { /* a node (cell) in a singly-link list */ intdata; /* the payload */ sNode* next; /* next node in list */ }; /* newitem: create new item from name and value */ sNode* newNode( int d ) { sNode *newp; newp = (sNode*) malloc( sizeof( sNode )); if( newp != NULL ) { newp->data = d; newp->next = NULL; } return newp; }

Lists in C /* addfront: add newp to front of listp * * return ptr to new list */ sNode* addfront( sNode *listp, sNode *newp ) { newp->next=listp; return newp; } list = addfront( list, newitem( 13 ));

Append Element to Back of List /* append: add newp to end of listp * * return ptr to new list */ sNode* addend( sNode *listp, sNode *newp ) { sNode *p; if( listp == NULL ) return newp; for( p=listp; p->next!=NULL; p=p->next ) ; p->next = newp; return listp; }

Lookup Element in List /* lookup: linear search for t in listp * * return ptr to node containing t, or NULL */ sNode* lookup( sNode *listp, int t ) { for( ; listp != NULL; listp = listp->next ) if( listp->data = t ) return listp; return NULL; /* no match */ }

Apply Function to Elements in List /* apply: execute fn for each element of listp */ void apply( sNode *listp, void (*fn)(sNode ), void* arg ) { for ( ; listp != NULL; listp = listp->next) (*fn)( listp, arg ); /* call the function */ } void (*fn)( sNode* ) is a pointer to a void function of one argument – the first argument is a pointer to a sNode and the second is a generic pointer.

Print Elements of a List /* printnv: print name and value using format in arg */ void printnv( sNode *p, void *arg ) { char *fmt; fmt = (char*) arg; printf( fmt, p->data ); } apply( list, printnv, “%d ” );

Count Elements of a List /* inccounter: increment counter *arg */ void incCounter( sNode *p, void *arg ) { int *ip; /* p is unused – we were called, there's a node */ ip = (int *) arg; (*ip)++; } int n = 0; /* n is an int, &n is its address (a ptr) */ apply( list, inccounter, &n ); printf( “%d elements in list\n”, n );

Free Elements in List /* freeall: free all elements of listp */ void freeall( sNode *listp ) { sNode *next; for ( ; listp != NULL; listp = next) { next = listp->next; free(listp) } ? for ( ; listp != NULL; listp = listp->next) ? free( listp );

Delete Element in List /* delitem: delete first t from listp */ sNode *delitem( sNode *listp, int t ) { sNode *p, *prev = NULL; for( p=listp; p!=NULL; p=p->next ) { if( p->data == t ) { if( prev == NULL ) /* front of list */ listp = p->next; else prev->next = p->next; free(p); break; } prev = p; } return listp;}

Linear Search Just exhaustively examine each element Works on any list (sorted or unsorted) Only search for a linked-list Examine each element in the collection, until you find what you seek, or you've examined every element Note that order of examination doesn't matter Need θ(n), worst and average

Linear Search - example L = range( 1, 11 ) # fill w/numbers 1-10 random.shuffle( L ) # mix it up target = 7 # we're looking for 7 i = 0 while i < len( L ) and not bFound : if L[i] == target : break i += 1 if i < len( L ) : # we found it! print str(target) + \ " was found at index " + str(i)

Binary Search Only works on sorted collections Only works on indexed collections (arrays, vectors) Start in the middle: Find it?  Less than? Look in lower ½  Greater than? Look in upper ½ Cut search space in ½ Need θ(lg(n)) time, worst (and avg.)

Binary Search # from previous example L.sort() # put into order t = 7 # our target i = -1 l = 0 ; h = len(L)-1 while l<=h and i==-1 : m = (l+h)/2# find middle element if( L[m] == t ) : # found i = m elif t < L[m] : # look in left ½ h = m – 1 else : # look in right ½ l = m + 1 if i != -1 : print "Found " + str(t) + " at " + str(i)

Quicksort pick one element of the array (pivot) partition the other elements into two groups those less than the pivot those that are greater than or equal to the pivot Pivot is now in the right place recursively sort each (strictly smaller) group

Partition unexaminedp lastie unexamined< pp>= p bb+1lastie < pp>= p blaste

Quicksort – the recursive algorithm def qsort( L, b, e ) : # base case if b >= e : # nothing to do - 0 or 1 element return; # partition returns index of pivot element piv = partition( L, b, e ) # Note that the pivot is right where it belongs # It does not get sent out in either call qsort( L, b, piv-1 ) # elements in [ b, piv ) qsort( L, piv+1, e ) # elements in ( piv, e ]

Quicksort – the Partition def partition( L, b, e ) : "Return: index of pivot" # move pivot element to L[0] swap( L, b, random.randint( b, e )) last = b # Move <p to left side, marked by `last' for i in range( b+1, e+1 ) : if L[i] < L[b] : last += 1 swap( L, last, i ) swap( L, b, last ) # restore pivot return last

Quicksort - Swap def swap( l, i, j ) : "swaps elements at indices i, j in list l" tmp = l[i] l[i] = l[j] l[j] = tmp

Libraries - sort C: qsort (in stdlib.h ) C++: sort (algorithm library from STL) Java: java.util.collections.sort Perl: sort Python: list.sort

qsort – standard C library qsort( void *a, int n, int s, int(*cmp)(void *a, void *b) ); Sorts array a, which has n elements Each element is s bytes cmp is a function that you must provide compares 2 single elements, *a & *b  qsort must pass void pointers (addresses), since it doesn't know the type  cmp does, since you provide it for a given sort returns integer -1 if a b For sorting in descending order, return 1 if a < b

qsort (int) int arr[N]; qsort(arr, N, sizeof(arr[0]), icmp); /* icmp: integer compare of *p1 and *p2 */ int icmp( const void *p1, const void *p2 ) { int v1, v2; v1 = *((int*) p1); v2 = *((int*) p2); if( v1 < v2 ) return –1; else if( v1 == v2 ) return 0; else return 1; }

qsort (strings) char *str[N]; qsort(str, N, sizeof(str[0]), scmp); /* scmp: string compare of *p1 and *p2 */ /* p1 is a ptr to a string, or char*, so is a */ /* ptr to a ptr, or a char** */ int scmp(const void *p1, const void *p2) { char *v1, *v2; v1 = *((char**) p1); v2 = *((char**) p2); return strcmp(v1, v2); }

Dictionary (Map) Allows us to associate satellite data w/a key e.g., phone book, student record (given a student ID as key), error string (given an error # as key), etc. Operations: insert find remove

Dictionary The key-value pairs may be stored in any aggregate type (list, struct, etc) Using an unordered list: constant-time insertion linear lookup Ordered list linear insertion lg(n) lookup

Other dictionaries Binary Search Tree lg(n) insertion, lookup (if balanced) Hash table constant-time insertion, lookup (if done well)

Trees A binary tree is either NULL or contains a node with the key/value pair, and a left and right child which are themselves trees. In a binary search tree (BST) the keys in the left child are smaller than the keys at the node and the values in the right child are greater than the value at the node. (Recursively true through all subtrees.) O(log n) expected search and insertion time in-order traversal provides elements in sorted order.

Examples In the following examples each node stores the key/value pair: name – a string value – a hex #, that represents the character (MBCS) As well as a reference (ptr) to each of the 2 subtrees

Trees in Python We can use a list of 3 elements: 0. The key/value pair 1. The left subtree 2. The right subtree The following is a tree w/one node (empty subtrees) T = [ ["Smiley", 0x263A], [], [] ]

BST Lookup - Python def lookup( T, name ) : """lookup: look up name in tree T, return the cell, None if not found""" if T == [] : # T is the empty tree return None if T[0][0] == name : return T elif name < T[0][0] : # look in left subtree return lookup( T[1], name ); else : # look in right subtree return lookup( T[2], name ); }

BST in C We will use a struct to hold the key, value, and pointers to the subtrees

Binary Search Tree typedef struct bNode bNode; struct Node { char *name; int value; sNode *left; sNode *right; }; “smiley” 0x263A “zeta” 0x03b6 NULL “smiley” 0x263A “smiley” 0x263A “smiley” 0x263A “Aacute” 0x00c1 “smiley” 0x263A “Acirc” 0x00c2 NULL “smiley” 0x263A “AElig” 0x00c6 NULL

Binary Search Tree Lookup /* lookup: look up name in tree treep */ sNode *lookup( sNode *treep, char *name ) { int cmp; if( treep == NULL ) return NULL; cmp = strcmp(name, tree->name); if( cmp == 0 ) return treep; else if( cmp < 0 ) return lookup( treep->left, name ); else return lookup( treep->right, name ); }

Hash Tables Provides key lookup and insertion with constant expected cost Used to create lookup table (with m slots), where it is not usually possible to reserve a slot for each possible element hash function maps key to index (should evenly distribute keys) H(k) -> [ 0, m-1 ] duplicates stored in a chain (list) – other mechanisms are possible.

Dictionaries in Python Python (as well as Perl and Awk) has a built-in dictionary (associative array) Type is dict d = {} # empty dictionary # initialise nvList = { 'Smiley': 0x263A, 'Aacute': 0x00c1 } print nvList[ 'Smiley' ]

Dictionaries - Python Add an entry: nvList[ 'Zeta', 0x03b6 ] Test for existence: if nvList.has_key( 'AElig' ) : Remove an entry: nvList.pop( 'Smiley', None ) Iterate over keys: for i in nvList.keys() :

Hash Table - C typedef struct sNode sNode; struct sNode { char *name; int value; sNode *next; /* in chain */ }; sNode *symtab[NHASH]; /* a symbol table */ NULL name 1 data 1 name 2 data 2 NULL name 3 data 3

Hash Table Lookup /* lookup: find name in symtab, with optional create */ sNode *lookup(char *name, int create, int value) { int h; sNode *sym; h = hash(name); for (sym = symtab[h]; sym != NULL; sym = sym->next) if (strcmp(name, sym->name) == 0) return sym; if (create) { sym = (sNode *) emalloc(sizeof(sNode)); sym->name = name; /* assumed allocated elsewhere */ sym->value = value; sym->next = symtab[h]; symtab[h] = sym; } return sym; }

Hash Function enum { MULTIPLIER = 31}; /* hash: compute hash value of string */ unsigned int hash(char* str) { unsigned int h; unsigned char *p; h = 0; for (p = (unsigned char *) str; *p != ‘\0’; p++) h = MULTIPLIER * h + *p; return h % NHASH; }