Download Extensible Array

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
no text concepts found
Transcript
Extensible Array
C and Data Structures
Baojian Hua
[email protected]
Data Structures

Data structure studies the organization of
data in computers, consisting of




Algorithms:



the (abstract) data types (definition and repr’)
relationship between elements of this type
operations on data types
operations on data structures
subtle interplay with data structure design
Slogan: program=data structures + algorithm
What will this part cover?

Linear structures:


Tree & forest:




extensible array, linked list, stack, queue,
string, etc.
binary tree, binary search tree
Graph
Hash
Sorting and Searching?
Linear Data Structures

A linear list (list) consists of:

a collection of data elements


elements are ordered:




e1, e2, …, en (n≥0)
e1≤e2≤ … ≤en
ei is called an predecessor of ei+1
ei+1 is called a successor of ei
every element has at most one successor
and one predecessor
Typical operations
// create an empty list
new ();
// the length of a list l
length (list l);
// insert element x at position i in l, 0<=i<n
insert (list l, x, i);
// return the i-th element
nth (list l, i);
// delete the element at position i in l, 0<=i<n
delete (list l, i);
// apply function f to each element in l
foreach (list l, f);
Polymorphic Abstract Data
Types in C
// in “list.h”
#ifndef LIST_H
#define LIST_H
typedef struct List_t *List_t;
List_t List_new ();
int List_length (List_t l);
poly List_nth (List_t l, int n); // “poly”?
void List_insert (List_t l, poly x, int i);
poly List_delete (List_t l, int i);
void List_foreach (List_t l, void (*f)(poly));
#endif
Implementations

Two well-known implementation
techniques:



array-based
linked structure-based
We next consider the first, and leave
the second to the next slide
Implementation Using Array

The straightforward method to implement
this interface (ADT) is to use an array
0

n-1
and the array may not be full, so we must keep a
“tail” tag to record its tail (the position of its last
elements)
Implementation Using Array

The straightforward method to implement
this interface is to use an array
tail
0

n-1
and the array may not be full, so we must keep a
“tail” tag to record its tail (the position of its last
elements)
1st Try
#define N 100
int main ()
{
int a[N];
int tail = 0;
tail
0
n-1
a[tail++] = 3;
a[tail++] = 5;
…
// what if we continue to insert value into “a”?
}
Array-based Implementation
// Combine these above observations, we have:
// in file “arrayList.c”
#include <stdlib.h>
#include “list.h”
#define INIT_LENGTH 32 l
#define EXT_FACTOR 2
struct List_t
{
poly *array;
int max;
int tail;
};
array
max
tail
0
n-1
Create an Empty List
List_t List_new ()
{
List_t l = malloc (sizeof (*l));
l->array = malloc (INIT_LENTH * sizeof(poly));
l->max = INIT_LENTH;
l->tail = 0;
return l;
}
Create an Empty List
List_t List_new ()
{
List_t l = malloc (sizeof (*l));
l->array = malloc (INIT_LENTH * sizeof(poly));
l->max = INIT_LENTH;
l->tail = 0;
return l;
}
l
$#%&
%$&^
@#%$
Create an Empty List
List_t List_new ()
{
List_t l = malloc (sizeof (*l));
l->array = malloc (INIT_LENTH * sizeof(poly));
l->max = INIT_LENTH;
l
l->tail = 0;
array
%$&^
return l;
@#%$
}
0
n-1
Create an Empty List
List_t List_new ()
{
List_t l = malloc (sizeof (*l));
l->array = malloc (INIT_LENTH * sizeof(poly));
l->max = INIT_LENTH ;
l
l->tail = 0;
array
return l;
}
max
@#%$
0
n-1
Create an Empty List
List_t List_new ()
{
List_t l = malloc (sizeof (*l));
l->array = malloc (INIT_LENTH * sizeof(poly));
l->max = INIT_LENTH ;
l
l->tail = 0;
array
return l;
}
max
tail
0
n-1
Operation: “length”
int List_length (List_t l)
{
// note that we omit such checks in the next
// for clarity. However, You should always do
// such kind of checks in your code.
assert(l);
l
array
return l->tail;
max
}
tail
0
n-1
Operation: “nth”
poly List_nth (List_t l, int i)
{
if (i<0 || i>=l->tail)
error (“invalid index”);
return (l->array)[i];
}
l
array
max
tail
0
n-1
Operation: “nth”
poly List_nth (List_t l, int i)
{
if (i<0 || i>=l->tail)
error (“invalid index”);
return (l->array)[i];
}
l
array
max
tail
i
0
temp
n-1
Operation: “insert”
void List_insert (List_t l, poly x, int i)
{
if (i<0 || i>l->tail)
error (“invalid index”);
//move the data
…;
}
l
array
max
tail
i
0
n-1
Operation: “insert”
void List_insert (List_t l, poly x, int i)
{
if (i<0 || i>l->tail)
error (“invalid index”);
l
for (int j=l->tail;
j>i; j--)
(l->array)[j] =
(l->array)[j-1];
…;
array
max
tail
i
}
0
j
n-1
Operation: “insert”
void List_insert (List_t l, poly x, int i)
{
if (i<0 || i>l->tail)
error (“invalid index”);
l
for (int j=l->tail;
j>i; j--)
(l->array)[j] =
(l->array)[j-1];
…;
array
max
tail
i
}
0
j
n-1
Operation: “insert”
void List_insert (List_t l, poly x, int i)
{
if (i<0 || i>l->tail)
error (“invalid index”);
l
for (int j=l->tail;
j>i; j--)
(l->array)[j] =
(l->array)[j-1];
…;
array
max
tail
i
}
0
j
n-1
Operation: “insert”
void List_insert (List_t l, void *x, int i)
{
if (i<0 || i>l->tail)
error (“invalid index”);
l
for (int j=l->tail;
j>i; j--)
(l->array)[j] =
(l->array)[j-1];
(l->array)[i] = x;
array
max
tail
i
x
}
0
j
n-1
Operation: “insert”
void List_insert (list l, void *x, int i)
{
if (i<0 || i>l->tail)
error (“invalid index”);
l
for (int j=l->tail;
j>i; j--)
(l->array)[j] =
(l->array)[j-1];
(l->array)[i] = x;
(l->tail)++;
array
max
tail
i
x
}
0
j
n-1
Perfect?

What if the
initial array look
like the right
one?

direct data
movement will
incur an out-ofbound error!
l
array
max
tail
i
0
n-1
Extensible Array
void List_insert (List_t l, poly x, int i)
{
if (i<0 || i>l->tail)
error (“invalid index”);
// if l is full, extend l->array by a factor…
if (l->tail==l->max) {
l->array = realloc (l->array,
EXT_FACTOR*(l->max)*sizeof(poly));
l->max *= EXT_FACTOR;
}
// data movement as discussed above…;
}
Extensible Array
l->array = realloc (l->array,
EXT_FACTOR*(l->max)*sizeof(poly));
l
array
max
tail
i
0
0
i
n-1
n-1
2n-1
Extensible Array
l->array = realloc (l->array,
EXT_FACTOR*(l->max)*sizeof(poly));
l
array
max
tail
i
0
0
n-1
i
n-1
2n-1
Extensible Array
l->array = realloc (l->array,
EXT_FACTOR*(l->max)*sizeof(poly));
l
array
l->max *= EXT_FACTOR;
max
tail
i
0
0
i
n-1
2n-1
Extensible Array
l
array
max
tail
i
0
n-1
2n-1
Operation: “delete”

The “delete” operation is reverse
operation of the “insert”



also involves data movement
should we shrink the extensible array,
when there are few elements in it (say ½
data item left)?
More tricky than first looks
Operation: “foreach”
void List_foreach (List_t l, void (*f)(poly))
{
for (int i=0; i<l->tail; i++)
f ((l->array)[i]);
return;
l
array
}
max
tail
0
n-1
Summary

Linear list ADT:



a collection of ordered data element
each item has no more than one successor or
predecessor
Extensible array-based implementation



maintain internally a dynamically extensible array
bad performance with insert or delete
space waste
Related documents