Computer programming - Lab 13

Abstract datatypes

1. Complex numbers Implement an abstract data type (including .h and .c file) for a complex number. Use a 64-bit value that encodes both real and imaginary part as 32-bit floats. Implement functions that construct a complex number given real and imaginary parts; extract real/imaginary part; multiply two complex numbers; print a complex number.

2. Bitsets Implement and test a library for sets of bounded unsigned integers, using one bit per element. The maximum bound for a set element is given at set creation time.

3. Date Implement an abstract data type (including .h and .c file) for a calendar date (including fields from year to second). Use a 32-bit integer, with separate bit fields for each component, having 1 January 1970 as starting point (note that the actual UNIX time representation continuously increments seconds and does not use separate bitfields). Implement functions that construct a date from 6 parameters, check if an integer represents a valid date, and compute the difference between two dates (in seconds), and extract day and month from a date. For one of the latter two functions use bitwise operators and for the other cast the pointer to the date value to a pointer to a structure with bitfields, and use those bitfields.

Lists

4. Delete duplicates Implement a function that takes a list of integers and removes any consecutive duplicates (leaving only one value from any sequence of equal values). Modify the list in place and free the memory for the deleted values.

5. Mergesort Write a function that sorts an integer list: 1) split it into two (almost) equal parts; 2) recursively sort the parts; 3) merge the sorted parts, by repeatedly choosing the smallest of the two values at the front of each list. Free all temporary allocated data.

6. Lists of lists Implement a datastructure for lists of integer lists. Use it to store integers read until end of input (separated by whitespace), each input line resulting in a list. Use the address of the (link) pointer to append each new integer to the end of the list for a line.

7. Lists and trees A binary tree with integer nodes is either the empty tree, or a node (root) with a left and a right subtree.
A binary tree with different values in each node may be uniquely reconstructed if the lists of its nodes in both preorder and inorder traversals are given.
Preorder traversal means visiting the root followed by the left and right subtree. Inorder traversal means visiting the left subtree, the root and then the right subtree. In both cases, subtrees are traversed in the same order as specified.
For example, given the lists:

preorder: [2; 7; 1; 6; 5; 11; 8; 9; 4]
inorder: [1; 7; 5; 6; 11; 2; 8; 4; 9]
the first element in the preorder list is the root. Searching for it in the inorder list splits the list into [1; 7; 5; 6; 11] for the left subtree and [8; 4; 9] for the right subtree (both inorder). Splitting the tail of the preorder list in pieces of the corresponding lengths produces the (preorder) lists [7; 1; 6; 5; 11] and [8; 9; 4]. Thus the problem is reduced to solving it recursively for the two subtrees.
Implement a function that takes two lists and returns the tree reconstructed from these lists. Do not destroy the original lists, but free any intermediate memory allocated. Report inconsistent input.
Simpler version: Solve the problem for arrays instead of lists. Avoid any copying in this case.


Marius Minea
Last modified: Wed Dec 21 18:35:00 EET 2016