Algorithms, Data Structures, and Problem Solving

Similar documents
Lecture 7: Data Structures. EE3490E: Programming S1 2017/2018 Dr. Đào Trung Kiên Hanoi Univ. of Science and Technology

Linked Lists in C and C++

CP2 Revision. theme: dynamic datatypes & data structures

Linked List. April 2, 2007 Programming and Data Structure 1

.:: UNIT 4 ::. STACK AND QUEUE

11 'e' 'x' 'e' 'm' 'p' 'l' 'i' 'f' 'i' 'e' 'd' bool equal(const unsigned char pstr[], const char *cstr) {

Cpt S 122 Data Structures. Data Structures

Programming. Lists, Stacks, Queues

Data Structure Series

Linear Structures. Linear Structure. Implementations. Array details. List details. Operations 4/18/2013

DC104 DATA STRUCTURE JUNE Q.2 a. If you are using C language to implement the heterogeneous linked list, what pointer type will you use?

CS 222: Linked Lists, Queues, Stacks

Linear Structures. Linear Structure. Implementations. Array details. List details. Operations 2/10/2013

In Java we have the keyword null, which is the value of an uninitialized reference type

Dynamic Data Structures

Data Structures. Outline. Introduction Linked Lists Stacks Queues Trees Deitel & Associates, Inc. All rights reserved.

EC8393FUNDAMENTALS OF DATA STRUCTURES IN C Unit 3

csci 210: Data Structures Stacks and Queues

advanced data types (2) typedef. today advanced data types (3) enum. mon 23 sep 2002 defining your own types using typedef

The time and space are the two measure for efficiency of an algorithm.

Big- (O): c.) binary search O(logn)

Linked List in Data Structure. By Prof. B J Gorad, BECSE, M.Tech CST, PHD(CSE)* Assistant Professor, CSE, SITCOE, Ichalkaranji,Kolhapur, Maharashtra

Data Structures and Algorithms (DSA) Course 5 Lists. Iulian Năstac

CSE 230 Intermediate Programming in C and C++

1 P age DS & OOPS / UNIT II

Lists, Stacks, and Queues. (Lists, Stacks, and Queues ) Data Structures and Programming Spring / 50

ECE264 Spring 2013 Final Exam, April 30, 2013

MULTIMEDIA COLLEGE JALAN GURNEY KIRI KUALA LUMPUR

3. Fundamental Data Structures

Cpt S 122 Data Structures. Course Review Midterm Exam # 1

1 P a g e A r y a n C o l l e g e \ B S c _ I T \ C \

libtools Documentation

Darshan Institute of Engineering & Technology for Diploma studies Unit 4

FORTH SEMESTER DIPLOMA EXAMINATION IN ENGINEERING/ TECHNOLIGY- OCTOBER, 2012 DATA STRUCTURE

malloc(), calloc(), realloc(), and free()

Advanced C Programming and Introduction to Data Structures

Queues. A queue is a special type of structure that can be used to maintain data in an organized way.

CS350 - Exam 1 (100 Points)

Lecture Notes CPSC 122 (Fall 2014) Today Quiz 7 Doubly Linked Lists (Unsorted) List ADT Assignments Program 8 and Reading 6 out S.

Solution for Data Structure

Programming in C. Lecture Tiina Niklander. Faculty of Science

III Data Structures. Dynamic sets

Elementary Data Structures: Part 1: Arrays, Lists. CSE 2320 Algorithms and Data Structures Vassilis Athitsos University of Texas at Arlington

BBM 201 DATA STRUCTURES

Lists, Stacks and Queues in C. CHAN Hou Pong, Ken CSCI2100A Data Structures Tutorial 4

How to Win Coding Competitions: Secrets of Champions. Week 2: Computational complexity. Linear data structures Lecture 5: Stack. Queue.

Discussion 2C Notes (Week 3, January 21) TA: Brian Choi Section Webpage:

Computer Science 210 Data Structures Siena College Fall Topic Notes: Linear Structures

Programs in memory. The layout of memory is roughly:

Data Abstractions. National Chiao Tung University Chun-Jen Tsai 05/23/2012

Data Representation and Storage. Some definitions (in C)

ECE264 Fall 2013 Exam 2, October 24, 2013

CS301 - Data Structures Glossary By

ESc101: (Linear, Circular, Doubly) Linked Lists, Stacks, Queues, Trees. Introduction to Linked Lists

Data Structures Question Bank Multiple Choice

Basic Data Structures (Version 7) Name:

Short Notes of CS201

CS 61C: Great Ideas in Computer Architecture C Pointers. Instructors: Vladimir Stojanovic & Nicholas Weaver

Kurt Schmidt. October 30, 2018

Linked lists. Insert Delete Lookup Doubly-linked lists. Lecture 6: Linked Lists

Recitation #11 Malloc Lab. November 7th, 2017

Programming and Data Structure Solved. MCQs- Part 2

CS 222: Pointers and Manual Memory Management

The combination of pointers, structs, and dynamic memory allocation allow for creation of data structures

Linked Lists and Abstract Data Structures A brief comparison

Two approaches. array lists linked lists. There are two approaches that you can take:

CS201 - Introduction to Programming Glossary By


+ Abstract Data Types

Data Representation and Storage

Week 7 Part I. Kyle Dewey. Monday, August 6, 12

Ashish Gupta, Data JUET, Guna

Data Structures and Algorithms. Roberto Sebastiani

LIFO : Last In First Out

Data Structures in C. C Programming and Software Tools. N.C. State Department of Computer Science

Midterm Review. CS 211 Fall 2018

(Section : Computer Science)

Actually, C provides another type of variable which allows us to do just that. These are called dynamic variables.

CMSC Introduction to Algorithms Spring 2012 Lecture 7

DOWNLOAD PDF LINKED LIST PROGRAMS IN DATA STRUCTURE

CS61, Fall 2012 Section 2 Notes

[CSE10200] Programming Basis ( 프로그래밍기초 ) Chapter 9. Seungkyu Lee. Assistant Professor, Dept. of Computer Engineering Kyung Hee University

PROGRAMMAZIONE I A.A. 2017/2018

C Programming, Autumn 2013, Exercises for the Second Week

Linked Lists

Advanced Pointer & Data Storage

C Data Structures Stacks. Stack. push Adds a new node to the top of the stack

CS 103 Unit 11. Linked Lists. Mark Redekopp

(6-1) Basics of a Queue. Instructor - Andrew S. O Fallon CptS 122 (September 26, 2018) Washington State University

CSC 1600 Memory Layout for Unix Processes"

CHARUTAR VIDYA MANDAL S SEMCOM Vallabh Vidyanagar

Information Science 2

Intermediate Programming, Spring 2017*

Arrays and Memory Management

Bit Manipulation in C

ENEE150 Final Exam Review

Department of Computer Science & Engineering Indian Institute of Technology Kharagpur. Practice Sheet #13

ECE264 Fall 2013 Exam 3, November 20, 2013

Singly linked lists in C.

Dynamic Memory Allocation

Transcription:

Algorithms, Data Structures, and Problem Solving Masoumeh Taromirad Hamlstad University DT4002, Fall 2016

Container Concepts containers store data container operations: insertion retrieval removal iteration possible organization types sequential associative unorganized

Conceptual Overview Sequence Containers http://en.wikipedia.org/wiki/file:rna-codons.png http://en.wikipedia.org/wiki/file:toppledominos.jpg serial arrangement of items

Conceptual Overview Sequence Containers common implementation approaches: array linked list singly or doubly linked linear or circular http://en.wikipedia.org/wiki/file:singly-linked-list.svg

Conceptual Overview Associative Containers connect each item with a key key

Conceptual Overview Associative Containers common implementation approaches: tree binary, k-ary, multiway,... balanced / complete /... hash table... http://en.wikipedia.org/wiki/file:b-tree.svg

Conceptual Overview Unorganized Containers no particular sequence or association internal structure depends on desired properties example: each item should be unique

Conceptual Overview Unorganized Containers common implementation approaches: tree hash table array list http://en.wikipedia.org/wiki/file:binary_tree.svg

Conceptual Overview Iteration a generic way of visiting each item the iteration order depends on: container organization type container implementation iteration algorithm classification: uni-directional bi-directional random access

Today Common Sequence Containers Vectors and Lists vectors are arrays that grow and shrink lists are containers where each item points to its successor (and sometimes predecessor)

Implementation Overview Arrays store user data in consecutive cells (memory locations) pre-allocate enough space the array is the address of the first item address offset of each item offset = index * sizeof(item)

Implementation Overview Arrays cell + 2 * sizeof(data)

Implementation Overview Arrays advantages: very simple lightweight random access potential drawbacks: fixed capacity insertion and removal can be costly

Implementation Overview Vectors (dynamic arrays) advantages: very simple lightweight random access potential drawbacks: fixed capacity insertion and removal can be costly

Implementation Overview Vectors dynamic size: get more memory when the array grows (optional) give back memory when it shrinks we need to: track the capacity track the current size manage memory (maybe) copy the contents after growing

Implementation Overview Vectors dynamic size: get more memory when the array grows (optional) give back memory when it shrinks we need to: track the capacity track the current size manage memory free (maybe) copy the contents after growing malloc, realloc, memcpy

unsigned int cap; unsigned int len; int * arr; Implementation Sketch Vectors /*... */ if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len;

unsigned int cap; unsigned int len; int * arr; Implementation Sketch Vectors /*... */ if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len; vector contents: index 0 1 2 value 42 77-123

unsigned int cap; unsigned int len; int * arr; /*... */ if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len; this is a pointer 0124 4 0128 3 012c 3b50 =cap =len =arr 3b50 42 3b54 77 3b58-123 3b60 vector contents: index 0 1 2 value 42 77-123

unsigned int cap; unsigned int len; int * arr; /*... */ let s append 321 if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len; 0124 4 0128 3 012c 3b50 false =cap =len =arr 3b50 42 3b54 77 3b58-123 3b60 vector contents: index 0 1 2 value 42 77-123

unsigned int cap; unsigned int len; int * arr; /*... */ let s append 321 if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len; 0124 4 0128 4 012c 3b50 =cap =len =arr 3b50 42 3b54 77 3b58-123 3b60 321 vector contents: index 0 1 2 3 value 42 77-123 321

unsigned int cap; unsigned int len; int * arr; /*... */ let s append -21 if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len; 0124 4 0128 4 012c 3b50 true =cap =len =arr 3b50 42 3b54 77 3b58-123 3b60 321 vector contents: index 0 1 2 3 value 42 77-123 321

unsigned int cap; unsigned int len; int * arr; /*... */ let s append -21 if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len; 0124 4 0128 4 012c 3b50 =cap =len =arr 3b50 42 3b54 77 3b58-123 3b60 321 vector contents: index 0 1 2 3 value 42 77-123 321 address a534 a538 a53c a540 a544 a548 a54c a550 value

unsigned int cap; unsigned int len; int * arr; /*... */ let s append -21 if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len; 0124 4 0128 4 012c 3b50 =cap =len =arr 3b50 42 3b54 77 3b58-123 3b60 321 vector contents: index 0 1 2 3 value 42 77-123 321 a534 42 a538 77 a53c -123 a540 321 a544 a548 a54c a550

unsigned int cap; unsigned int len; int * arr; /*... */ let s append -21 if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len; 0124 4 0128 4 012c 3b50 =cap =len =arr vector contents: index 0 1 2 3 value 42 77-123 321 a534 42 a538 77 a53c -123 a540 321 a544 a548 a54c a550

unsigned int cap; unsigned int len; int * arr; /*... */ let s append -21 if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len; 0124 8 0128 4 012c a534 =cap =len =arr vector contents: index 0 1 2 3 value 42 77-123 321 a534 42 a538 77 a53c -123 a540 321 a544 a548 a54c a550

unsigned int cap; unsigned int len; int * arr; /*... */ let s append -21 if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len; 0124 8 0128 5 012c a534 =cap =len =arr vector contents: index 0 1 2 3 4 a534 42 a538 77 a53c -123 a540 321 a544-21 a548 a54c a550 value 42 77-123 321-21

remember to clean up unsigned int cap; unsigned int len; int * arr; after yourself! if you forget to free, you ll create a leak /*... */ if (len >= cap) { newcap = 2*cap; newarr = malloc (newcap*sizeof(int)); memcpy (newarr, arr, len*sizeof(int)); free (arr); arr = newarr; cap = newcap; arr[len] = val; ++len; vector contents: index 0 1 2 3 4 value 42 77-123 321-21

Implementation Overview Linked Lists wrap user data into list nodes ( items ) links between nodes links to first (and last) node links are implemented with pointers look at three examples: simply linked list doubly linked list circular list

Implementation Overview Linked Lists NULL

Implementation Overview Linked Lists advantages: simple lightweight unlimited capacity potential drawback: no random access

Intermezzo Important Elements of C structs encapsulate information required to manage a data structure we ll frequently store pointers functions encapsulate the computations required for operations on a data structure introduced last week, practice this week we ll frequently pass pointers

Structs Define New Types struct name_s { ; char *first, *last; struct date_s { int year, day; char *month; ; structs contains fields, each field has a type and a name struct person { struct name_s name; struct date_s birthday; ; structs can be nested

Structs Storage Examples struct name_s { char *first, *last; ; struct date_s { int year, day; char *month; ; first 4108 44b4 last 410c 4800 44b4 B 44b5 44b6 o b 44b7 0 struct person_s { struct name_s name; struct date_s birthday; ; 4800 D 4801 o 4802 e 4803 0

Structs Storage Examples struct name_s { ; char *first, *last; struct date_s { int year, day; char *month; ; struct person_s { struct name_s name; struct date_s birthday; ; name first 7290 44b4 last 7294 4800 year 7298 1999 birthday day 729c 17 month 72a0 49a4

Field Access and Pointers struct person_s bob; bob.name.first = Bob ; bob.birthday.year = 1999; /* etc */ struct person_s *alice; alice = malloc (sizeof(*alice)); alice->name.first = Alice ; /* etc */ struct person_s *p1, *p2; p1 = &bob; p2 = alice;

Field Access and Pointers struct person_s bob; bob.name.first = Bob ; bob.birthday.year = 1999; /* etc */ struct person_s *alice; alice = malloc (sizeof(*alice)); alice->name.first = Alice ; /* etc */ dot notation for value-variables arrow notation for pointer-variables Note: alice->name is a value here struct person_s *p1, *p2; p1 = &bob; p2 = alice;

...back to Linked Lists NULL

struct item { int value; struct item * next; ; struct item *head, *tail; Implementation Sketch Lists /*... */ struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it;

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ variables head 0124 NULL tail 0128 NULL it 012c NULL struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; list contents: null

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ let s append 42 struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; variables list contents: head 0124 NULL tail 0128 NULL it 012c 21c8 value next address 21c8 21cc null value

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ let s append 42 struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; true variables list contents: head 0124 NULL tail 0128 NULL it 012c 21c8 value 21c8 42 next 21cc NULL null

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ let s append 42 struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; variables head 0124 21c8 tail 0128 21c8 it 012c 21c8 value 21c8 42 next 21cc NULL list contents: 42 null

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ let s append 17 struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; variables head 0124 21c8 tail 0128 21c8 it 012c 21c8 value 21c8 42 next 21cc NULL list contents: 42 null

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ let s append 17 struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; false variables head 0124 21c8 tail 0128 21c8 it 012c 4f10 value 21c8 42 next 21cc NULL value 4f10 17 next 4f14 NULL list contents: 42 null

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ let s append 17 struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; variables head 0124 21c8 tail 0128 21c8 it 012c 4f10 value 21c8 42 next 21cc NULL value 4f10 17 next 4f14 NULL list contents: 42 null

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ let s append 17 struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; variables head 0124 21c8 tail 0128 21c8 it 012c 4f10 value 21c8 42 next 21cc NULL value 4f10 17 next 4f14 NULL list contents: 42 null

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ let s append 17 struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; variables head 0124 21c8 tail 0128 21c8 it 012c 4f10 value 21c8 42 next 21cc NULL value 4f10 17 next 4f14 NULL list contents: 42 null

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ let s append 17 struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; variables head 0124 21c8 tail 0128 21c8 it 012c 4f10 value 21c8 42 next 21cc 4f10 value 4f10 17 next 4f14 NULL list contents: 42 17 null

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ let s append 17 struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; variables head 0124 21c8 tail 0128 4f10 it 012c 4f10 value 21c8 42 next 21cc 4f10 value 4f10 17 next 4f14 NULL list contents: 42 17 null

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ variables head 0124 21c8 tail 0128 4f10 it 012c 4f10 struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; value 21c8 42 next 21cc 4f10 value 4f10 17 next 4f14 NULL list contents: 42 17 null

struct item { int value; struct item * next; ; struct item *head, *tail; /*... */ struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it; sooner or later we must free the memory allocated here

struct item { int value; struct item * next; ; struct item *head, *tail; Implementation Sketch Lists /*... */ struct item * it; it = malloc (sizeof(*it)); it->value = value; it->next = NULL; if (NULL == head) { head = it; tail = it; else { tail->next = it; tail = it;

A Typical List Operation Function int list_append (struct list_s * list, int val) { struct item * it; it if = (NULL malloc == (sizeof(*it)); (it = malloc (sizeof(*it)))) it->value return -1; = value; it->next it->value = = NULL; value; if it->next (NULL == NULL; head) { if head (NULL = == it; list->head) { tail list->head = it; = it; list->tail = it; else { else tail->next { = it; tail list->tail->next = it; = it; list->tail = it; return 0;

A Typical List Operation Function int list_append (struct list_s * list, int val) { struct item * it; if (NULL == (it = malloc (sizeof(*it)))) return -1; it->value = value; it->next = return NULL; value indicates success / failure if (NULL == list->head) { list->head = it; list->tail = it; else { list->tail->next = it; list->tail = it; return 0; pointer to the list that should get modified

typedef struct item_s { int value; struct item_s *next; Item; typedef struct list_s { Item *head, *tail; List; void list_init (List *ll); void list_destroy (List *ll); int list_append (List *ll, int val); int list_insert (List *ll, Item *pos, int val); int list_remove (List *ll, Item *it); /* etc... */ Typical List Declarations

Typical List Declarations typedef struct item_s { int value; struct item_s *next; Item; typedef struct list_s { Item *head, *tail; List; these have to free memory allocated elsewhere void list_init (List *ll); void list_destroy (List *ll); int list_append (List *ll, int val); int list_insert (List *ll, Item *pos, int val); int list_remove (List *ll, Item *it); /* etc... */

Common List Variations doubly-linked list each item also knows its predecessor circular list the tail s successor is the first node the head s predecessor is the last node (for doubly-linked circular lists)

Common List Variations doubly-linked list head next next next null null prev prev prev tail circular list head next next next prev prev prev tail

Common List Specializations stack (LIFO - last in first out): push, pop, top queue (FIFO - first in first out): enqueue (insert at the end) dequeue (remove from the front) get (retrieve from the front) deque (double-ended queue): enqueue at front or end dequeue at front or end get at front or end

Iteration visit each item of a container vectors: just use array index can go forward, backward can even jump around (random access) lists: just use list nodes can go forward doubly-linked nodes can also go backward no random access

Vector Iteration struct vector_s { int *arr; unsigned long cap; unsigned long len; ; struct vector_s *vec; /*... */ unsigned long i; for (i = 0; i < vec->len; ++i) printf ( %d\n, vec->arr[i]);

List Iteration struct item_s { int value; struct item_s * next; ; struct list_s { struct item_s * head; ; struct list_s * list; /*... */ struct item_s * it; for (it = list->head; NULL!= it; it = it->next) printf ( %d\n, it->value);

...almost done... Some Lose Ends store something other than integers copy-paste-adapt (easy but tedious) generics (reusable but trickier) void pointers pointer casts common list implementation glitches order of link reassignments list insertion after tail or before head

Changing the Item Type struct int_vector_s { int *arr; size_t len, cap; ; int int_vector_append ( struct int_vector_s *vec, int val);

Changing the Item Type struct complex_s { ; double real, imag; struct cpx_vector_s { struct complex_s *arr; size_t len, cap; ; int cpx_vector_append ( struct cpx_vector_s *vec, struct complex_s val);

Changing the Item Type struct complex_s { ; double real, imag; struct complex_vector_s { struct complex_s *arr; size_t len, cap; ; this is trivial only for item types that can be bitwise copied by int complex_vector_append ( the compiler struct complex_vector_s *vec, struct complex_s val);

Changing the Item Type struct person_vector_s { struct person_s **arr; size_t len, cap; ; storing pointers to items is more generic than storing their values int person_vector_append ( struct person_vector_s *vec, struct person_s *val); but now ownership management becomes really important (more details later)

The Same for Lists struct person_item_s { struct person_s *value; struct person_item_s *next; ; struct item_s { int value; struct item_s *next; ; struct person_list_s { struct person_item_s *head, *tail; ; int person_list_append ( struct person_list_s * list, struct person_s *value);

Generic Item Type struct item_s { void *value; struct item_s *next; ; struct list_s { struct item_s *head, *tail; ; int list_append ( struct list_s * list, void *value); struct list_s * list; struct person_s * bob; /*... */ list_append (list, bob);

Generic Item Type struct item_s { void *value; struct item_s *next; ; struct list_s { struct item_s *head, *tail; ; int list_append ( struct list_s * list, void *value); struct list_s * list; struct person_s * bob; /*... */ list_append (&list, &bob); to retrieve values, we need to cast from void* to the correct type and more importantly, the memory occupied by bob needs to remain valid until list is destroyed!

Take-Home Message containers serve to store, look up, remove, and iterate over data items sequence containers store a serial arrangement of data items vectors and linked lists are the fundamental sequence container types stacks (LIFO), queues (FIFOs), and other variations are easily built on top of lists