Skip to content

Commit 2de6c00

Browse files
ClémentClément
authored andcommitted
Merge branch 'main' of github.com:princomp/princomp.github.io
2 parents d186f18 + 47a7f69 commit 2de6c00

4 files changed

Lines changed: 160 additions & 9 deletions

File tree

source/code/projects/CQueue/CQueue/CQueue.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ class CQueue<T>
55
private int front,
66
end,
77
size;
8+
89
private T[] mArray;
910

1011
public CQueue(int capacity = 10)
@@ -31,11 +32,11 @@ public bool IsFull()
3132
return size == mArray.Length;
3233
}
3334

34-
public void Enqueue(T newItem)
35+
public void Enqueue(T dataP)
3536
{
3637
if (!IsFull())
3738
{
38-
mArray[end] = newItem;
39+
mArray[end] = dataP;
3940
Increment(ref end);
4041
size++;
4142
}
@@ -53,23 +54,26 @@ public T Dequeue()
5354

5455
public void Resize()
5556
{
56-
throw new Exception(
57-
"Queue Resize is not implemented - you could implement it"
57+
throw new NotImplementedException(
58+
"Queue Resize is not implemented."
5859
);
5960
}
6061

6162
// Increment must be done carefully:
62-
// what if we reached the "end of mArray"
63-
// but there is room available at the
64-
// beginning of the queue? Then the value
65-
// needs to become 0.
63+
// if we reached the "end" of mArray,
64+
// then the value needs to become 0:
65+
// we resume "circling" through the
66+
// array.
6667
private void Increment(ref int value)
6768
{
6869
value++;
6970
if (value == mArray.Length)
7071
{
7172
value = 0;
7273
}
74+
// This if statement could be replaced
75+
// with
76+
// value %= mArray.Length;
7377
}
7478

7579
public int Capacity
@@ -82,6 +86,7 @@ public override string ToString()
8286
string returned = "";
8387
returned +=
8488
$"Front : {front}, end : {end}, size : {size}, capacity: {Capacity}\n";
89+
// Note how the for is constructed:
8590
for (int i = front; i < size + front; i++)
8691
{
8792
returned += mArray[i % mArray.Length] + ":";

source/lectures/data/queue.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,38 @@ Our implementation can recover the capacity of the queue by using:
7878
```
7979
capacity = mArray.Length - size;
8080
```
81-
.
81+
82+
However, trying to recover the size from the `front` and `end` values is not possible.
83+
One could try, using
84+
85+
```
86+
public int CSize
87+
{
88+
get
89+
{
90+
int csize = 0;
91+
if (front < end) { csize = end - front; }
92+
else if (front == end) { csize = mArray.Length; }
93+
else
94+
{
95+
csize = mArray.Length - front + end;
96+
}
97+
if (csize != size)
98+
{
99+
throw new NotImplementedException("CSize is not correctly implemented!");
100+
}
101+
return csize;
102+
}
103+
}
104+
```
105+
106+
but the exception would be thrown: can you figure out in which case(s) the "computed size" would be incorrect?
107+
<details>
108+
<summary>Solution</summary>
109+
The implementation is *almost* correct, the problem is that `front == end` can be true for two reasons:
110+
111+
#. The queue is empty, no element have been added yet (hence, size should be 0),
112+
#. The queue is full, no element can be added (hence, size should be `mArray.Length`).
113+
114+
Since `IsFull`, `IsEmpty` and `Capacity` all uses `size`, we have no way of telling if we are in the first or second situation. The rest of the implementation is correct, but `size` must be an attribute to be able to differenciate those two cases (note that we could also have added a `bool` to distinguish between "full" and "empty", but it's more convenient to have a `size` attribute available at all time).
115+
</details>

source/order

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
./exercises/data/
9696
./exercises/data/1darrays.md
9797
./exercises/data/2darrays.md
98+
./exercises/data/lists.md
9899
./exercises/control/
99100
./exercises/control/conditionals.md
100101
./exercises/control/iteratives.md

source/solutions/data/lists.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
---
2+
tags:
3+
- datatypes/collections
4+
---
5+
6+
# Lists (Solutions)
7+
8+
## Multiple Choices
9+
10+
#. Put a checkmark in the box corresponding to true statements about the List abstract data type.
11+
12+
- [ ] A list contains an finite collection of elements, in a particular order.
13+
- [ ] A list cannot contain multiple elements with the same value.
14+
- [x] A list must have a fixed number of elements.
15+
- [x] A list is generally endowed with an operation to test for emptiness.
16+
- [ ] Only the element at the beginning of a list can be removed.
17+
18+
19+
<details>
20+
<summary>Comments on the solution</summary>
21+
22+
- A list cannot contain an *infinite* collection of elements.
23+
- A list can have repetition, the same value can be present multiple times.
24+
- At any given time, a list has a fixed size.
25+
- This is *generally* the case in definitions of lists.
26+
- This restriction applies to queues or stacks (depending how "beginning" is interpreted), but not to lists.
27+
</details>
28+
29+
30+
## Exercises
31+
32+
#. Given the usual implementation of `Cell` and `CList`:
33+
34+
```
35+
public class CList<T>{
36+
private Cell first;
37+
private class Cell{
38+
public T Data { get; set; }
39+
public Cell Next { get; set; }
40+
public Cell(T dataP, Cell nextP){Data = dataP; Next = nextP;}
41+
}
42+
public CList(){first = null;}
43+
}
44+
```
45+
Write…
46+
47+
#. … a `IsEmpty` property that is `true` if the `CList` calling object is empty.
48+
49+
<details>
50+
<summary>Solution</summary>
51+
52+
Note that the question asks for a *property*:
53+
54+
```
55+
public bool IsEmpty{
56+
get{ return first == null; }
57+
}
58+
```
59+
</details>
60+
#. … the `AddF` method that add a cell at the beginning of the CList (to the left).
61+
62+
<details>
63+
<summary>Solution</summary>
64+
65+
The key is to use the given `Cell` constructor to create the new element:
66+
67+
```
68+
public void AddF(T dataP){
69+
first = new Cell(dataP, first);
70+
}
71+
```
72+
</details>
73+
#. … a series of statements, to be inserted in a `Main` method, that a. create a `CList` object capable of containing `char`, b. insert the elements `'b'` and `'/'` in it, c. displays whether it is empty using `IsEmpty`.
74+
75+
<details>
76+
<summary>Solution</summary>
77+
78+
Remembering that `IsEmpty` is a property, we obtain:
79+
80+
```
81+
CList<char> myList1 = new CList<char>();
82+
myList1.AddF('b');
83+
myList1.AddF('/');
84+
Console.WriteLine("myList1 is empty:" + myList1.IsEmpty);
85+
```
86+
</details>
87+
88+
#. Briefly explain the purpose of the `IsReadonly` property from the `ICollection<T>` interface, and list at least two methods in a List implementation realizing `ICollection<T>` that should use it.
89+
90+
<details>
91+
<summary>Solution</summary>
92+
This property indicates whether the `ICollection<T>` is read-only: if set to `true`, the `ICollection<T>` object should not accept addition or removal of elements.
93+
Hence, any method involving adding (`AddF`, `AddL`, …) or removing (`Clear`, `RemoveF`, `RemoveL`, `RemoveI`, …) values should test whether `IsReadonly` is `true` before proceeding.
94+
</details>
95+
96+
#. Explain the main differences between singly linked list and doubly linked list, and name a few methods that need to be implemented differently.
97+
98+
<details>
99+
<summary>Solution</summary>
100+
Doubly linked lists use a `Cell` class that contains *two* references: in addition to containing a reference to the `Cell` coming "after" themselves, as in singly linked lists, they also contain a reference to the `Cell` that is "before" them. This also requires to manipulate two references for the list: in addition to one reference to the first element (now called `Head`), as in singly linked list, they contain a reference to the "last" element (called `Tail`).
101+
102+
Clearing the list, adding and removing an element need to be implemented differently, as more references need to be updated.
103+
</details>
104+
105+
#. For what operation(s) does doubly linked list provide a complexity gain over singly linked list?
106+
107+
<details>
108+
<summary>Solution</summary>
109+
Inserting at the end of the list is $O(c)$ for doubly linked list, but $O(n)$ for singly linked list.
110+
In general, traversing the list in reverse order is less costly if the list is doubly linked.
111+
</details>

0 commit comments

Comments
 (0)