Up to Ex34.
This commit is contained in:
parent
24c637cb41
commit
dd1244294e
|
@ -11,27 +11,54 @@ Common Undefined Behavior
|
||||||
The Plan
|
The Plan
|
||||||
====
|
====
|
||||||
|
|
||||||
|
Review the issues around Undefined and Unspecified Behavior (UB).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Read The Book
|
||||||
|
====
|
||||||
|
|
||||||
|
The book lists many of the UB and discusses why they are important to know
|
||||||
|
about.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The Code
|
The Code
|
||||||
====
|
====
|
||||||
|
|
||||||
|
There is no code for this exercise, just a quick discussion for the book.
|
||||||
|
|
||||||
|
|
||||||
The Analysis
|
|
||||||
|
Undefined Behavior
|
||||||
====
|
====
|
||||||
|
|
||||||
|
* Compiler writers can do whatever they want.
|
||||||
|
* This means even *nothing*, which will ruin you silently.
|
||||||
|
* It's best to avoid it.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Breaking It
|
Unspecified Behavior
|
||||||
====
|
====
|
||||||
|
|
||||||
|
* For practical purposes unspecified is the same as undefined.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Handy Tools
|
||||||
|
====
|
||||||
|
|
||||||
|
* Clang's UB helpful flags.
|
||||||
|
* Lint tools and static analyzers.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Extra Credit
|
Extra Credit
|
||||||
====
|
====
|
||||||
|
|
||||||
|
Spend a day reading through as much of the UB as you can and find examples of each. Expect lots of frustration and failure when you do this.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
End Of Lecture 31
|
End Of Lecture 31
|
||||||
|
|
|
@ -11,10 +11,48 @@ Double Linked Lists
|
||||||
The Plan
|
The Plan
|
||||||
====
|
====
|
||||||
|
|
||||||
|
Learn about your very first data structure:
|
||||||
|
|
||||||
|
Double Linked Lists
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
Creating A liblcthw Project
|
||||||
|
====
|
||||||
|
|
||||||
|
We'll need a project for the rest of the book called *liblcthw*.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Algorithms and Data Structures
|
||||||
|
====
|
||||||
|
|
||||||
|
A big step in going from amateur to professional is learning
|
||||||
|
about data structures and algorithms.
|
||||||
|
|
||||||
|
A double linked list is the easiest one.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Double Linked Lists Visually
|
||||||
|
====
|
||||||
|
|
||||||
|
I'll quickly draw some diagrams to show you how they work.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Double Linked Lists in Python
|
||||||
|
====
|
||||||
|
|
||||||
|
Now let's see them in Python.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The Code
|
The Code
|
||||||
====
|
====
|
||||||
|
|
||||||
|
Now we can see the C code.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The Analysis
|
The Analysis
|
||||||
|
@ -22,16 +60,39 @@ The Analysis
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Improving It
|
||||||
Breaking It
|
|
||||||
====
|
====
|
||||||
|
|
||||||
|
* You can make ``List_clear_destroy`` more efficient by using
|
||||||
|
``LIST_FOREACH`` and doing both ``free`` calls inside one
|
||||||
|
loop.
|
||||||
|
* You can add asserts for preconditions so that the program isn't given a ``NULL``
|
||||||
|
value for the ``List *list`` parameters.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Improving It
|
||||||
|
====
|
||||||
|
|
||||||
|
* You can add invariants that check that the list's contents are always correct,
|
||||||
|
such as ``count`` is never ``< 0``, and if ``count > 0``, then ``first`` isn't NULL.
|
||||||
|
* You can add documentation to the header file in the form of comments before
|
||||||
|
each struct, function, and macro that describes what it does.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Extra Credit
|
Extra Credit
|
||||||
====
|
====
|
||||||
|
|
||||||
|
* Research doubly vs. singly linked lists and when one is preferred over
|
||||||
|
the other.
|
||||||
|
* Research the limitations of a doubly linked list. For example, while they
|
||||||
|
are efficient for inserting and deleting elements, they are very slow for
|
||||||
|
iterating over them all.
|
||||||
|
* What operations are missing that you can imagine needing? Some examples
|
||||||
|
are copying, joining, and splitting. Implement these operations and write the
|
||||||
|
unit tests for them.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
End Of Lecture 32
|
End Of Lecture 32
|
||||||
|
|
|
@ -11,27 +11,80 @@ Linked List Algorithms
|
||||||
The Plan
|
The Plan
|
||||||
====
|
====
|
||||||
|
|
||||||
|
Learn two sorting algorithms for double linked lists.
|
||||||
|
|
||||||
The Code
|
|
||||||
|
|
||||||
|
Bubble Sort
|
||||||
====
|
====
|
||||||
|
|
||||||
|
Explaining how bubble sort works visually.
|
||||||
|
|
||||||
|
|
||||||
The Analysis
|
|
||||||
|
Merge Sort
|
||||||
====
|
====
|
||||||
|
|
||||||
|
Explaining how bubble sort works visually.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The Unit Test Code
|
||||||
|
====
|
||||||
|
|
||||||
|
We'll do the unit test for this first since we know what the
|
||||||
|
results should be.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The Implementation
|
||||||
|
====
|
||||||
|
|
||||||
|
Once we have the test and it's failing we simply implement it.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Improving It
|
||||||
|
====
|
||||||
|
|
||||||
|
* The merge sort does a crazy amount of copying and creating lists, so find ways to reduce this.
|
||||||
|
* The bubble sort description in Wikipedia mentions a few optimizations. Try to implement them.
|
||||||
|
* Can you use the ``List_split`` and ``List_join`` (if you implemented them) to improve merge sort?
|
||||||
|
* Go through of all the defensive programming checks and improve the robustness of
|
||||||
|
this implementation, protecting against bad ``NULL`` pointers, and then create
|
||||||
|
an optional debug level invariant that works like ``is_sorted`` does
|
||||||
|
after a sort.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Breaking It
|
Breaking It
|
||||||
====
|
====
|
||||||
|
|
||||||
|
* Overload the data structure to hit the worst case time complexity.
|
||||||
|
* Give it a bad data structure.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Extra Credit
|
Extra Credit
|
||||||
====
|
====
|
||||||
|
|
||||||
|
* Create a unit test that compares the performance of the two algorithms. You'll want to look at ``man 3 time`` for a basic timer function,
|
||||||
|
and run enough iterations to at least have a few seconds of samples.
|
||||||
|
* Play with the amount of data in the lists that need to be sorted and see if that changes your timing.
|
||||||
|
* Find a way to simulate filling different sized random lists, measuring how long they take. Then, graph the result to see how it compares to the
|
||||||
|
description of the algorithm.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Extra Credit
|
||||||
|
====
|
||||||
|
|
||||||
|
* Try to explain why sorting linked lists is a really bad idea.
|
||||||
|
* Implement a ``List_insert_sorted`` that will take a given value, and using the ``List_compare``, insert the element at the
|
||||||
|
right position so that the list is always sorted. How does using this method compare to sorting a list after you've built it?
|
||||||
|
* Try implementing the bottom-up merge sort described on the Wikipedia page. The code there is already C, so it should be easy to
|
||||||
|
recreate, but try to understand how it's working compared to the slower one I have here.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
End Of Lecture 33
|
End Of Lecture 33
|
||||||
|
|
Loading…
Reference in New Issue