|
|
@ -0,0 +1,135 @@
|
|
|
1
|
module DataStructures where
|
|
|
2
|
|
|
|
3
|
import Prelude hiding (concat, drop, last, length, reverse, take)
|
|
|
4
|
|
|
|
5
|
class Seq s where
|
|
|
6
|
first :: s a -> Maybe a
|
|
|
7
|
|
|
|
8
|
last :: s a -> Maybe a
|
|
|
9
|
last s | isEmpty s = Nothing
|
|
|
10
|
last s | isEmpty (rest s) =
|
|
|
11
|
case first s of
|
|
|
12
|
Just x -> Just x
|
|
|
13
|
last s = last $ rest s
|
|
|
14
|
|
|
|
15
|
cons :: a -> s a -> s a
|
|
|
16
|
nil :: s a
|
|
|
17
|
|
|
|
18
|
rest :: s a -> s a
|
|
|
19
|
|
|
|
20
|
length :: s a -> Integer
|
|
|
21
|
length s | isEmpty s = 0
|
|
|
22
|
length s = 1 + length (rest s)
|
|
|
23
|
|
|
|
24
|
isEmpty :: s a -> Bool
|
|
|
25
|
|
|
|
26
|
fromList :: (Seq s) => [a] -> s a
|
|
|
27
|
fromList [] = nil
|
|
|
28
|
fromList (x:xs) = cons x $ fromList xs
|
|
|
29
|
|
|
|
30
|
butLast :: (Seq s) => s a -> s a
|
|
|
31
|
butLast s | isEmpty s = nil
|
|
|
32
|
butLast s =
|
|
|
33
|
case first s of
|
|
|
34
|
Just x -> cons x $ butLast (rest s)
|
|
|
35
|
|
|
|
36
|
drop :: (Seq s) => Integer -> s a -> s a
|
|
|
37
|
drop 0 s = s
|
|
|
38
|
drop _ s | isEmpty s = nil
|
|
|
39
|
drop n s = drop (n-1) $ rest s
|
|
|
40
|
|
|
|
41
|
take :: (Seq s) => Integer -> s a -> s a
|
|
|
42
|
take 0 _ = nil
|
|
|
43
|
take n s =
|
|
|
44
|
case first s of
|
|
|
45
|
Nothing -> nil
|
|
|
46
|
Just x -> cons x $ take (n-1) (rest s)
|
|
|
47
|
|
|
|
48
|
append :: (Seq s) => a -> s a -> s a
|
|
|
49
|
append x s | isEmpty s = cons x nil
|
|
|
50
|
append x s =
|
|
|
51
|
case first s of
|
|
|
52
|
Just x -> cons x $ append x (rest s)
|
|
|
53
|
|
|
|
54
|
concat :: (Seq s) => s a -> s a -> s a
|
|
|
55
|
concat l r | isEmpty l = r
|
|
|
56
|
concat l r | isEmpty r = l
|
|
|
57
|
concat l r =
|
|
|
58
|
case first l of
|
|
|
59
|
Just x -> cons x $ concat (rest l) r
|
|
|
60
|
|
|
|
61
|
reverse :: (Seq s) => s a -> s a
|
|
|
62
|
reverse s = rev s nil
|
|
|
63
|
where rev l r | isEmpty l = r
|
|
|
64
|
rev l r =
|
|
|
65
|
case first l of
|
|
|
66
|
Nothing -> nil
|
|
|
67
|
Just x -> rev (rest l) $ cons x r
|
|
|
68
|
|
|
|
69
|
data List a = Nil | Cons a (List a) deriving Show
|
|
|
70
|
|
|
|
71
|
-- first and cons are O(1), everything else is O(n)
|
|
|
72
|
instance Seq List where
|
|
|
73
|
first Nil = Nothing
|
|
|
74
|
first (Cons x _) = Just x
|
|
|
75
|
|
|
|
76
|
cons x l = Cons x l
|
|
|
77
|
nil = Nil
|
|
|
78
|
|
|
|
79
|
rest Nil = Nil
|
|
|
80
|
rest (Cons _ l) = l
|
|
|
81
|
|
|
|
82
|
isEmpty Nil = True
|
|
|
83
|
isEmpty _ = False
|
|
|
84
|
|
|
|
85
|
-- fifo, remove from front, insert into rear
|
|
|
86
|
data BankersQueue a = BankersQueue {
|
|
|
87
|
frontSize :: Integer,
|
|
|
88
|
front :: List a,
|
|
|
89
|
rearSize :: Integer,
|
|
|
90
|
rear :: List a
|
|
|
91
|
} deriving (Show)
|
|
|
92
|
|
|
|
93
|
enqueue x (BankersQueue fs f rs r) = check $ BankersQueue fs f (rs + 1) (cons x r)
|
|
|
94
|
|
|
|
95
|
dequeue (BankersQueue fs Nil rs Nil) = Nothing
|
|
|
96
|
dequeue (BankersQueue fs Nil rs r) = Just (x, check $ BankersQueue fs Nil (rs - 1) r')
|
|
|
97
|
where (Just x) = last r
|
|
|
98
|
r' = butLast r
|
|
|
99
|
dequeue (BankersQueue fs (Cons x fr) rs r) =
|
|
|
100
|
Just (x, check $ BankersQueue (fs - 1) fr rs r)
|
|
|
101
|
|
|
|
102
|
dequeueN 0 q = Nothing
|
|
|
103
|
dequeueN 1 q = dequeue q >>= \(x, _) -> return x
|
|
|
104
|
dequeueN n q = dequeue q >>= \(_, q') -> dequeueN (n-1) q'
|
|
|
105
|
|
|
|
106
|
check q@(BankersQueue fs f rs r) =
|
|
|
107
|
if rs <= fs
|
|
|
108
|
then q
|
|
|
109
|
else BankersQueue (fs + rs) (f `concat` reverse r) 0 Nil
|
|
|
110
|
|
|
|
111
|
instance Seq BankersQueue where
|
|
|
112
|
first (BankersQueue _ Nil _ r) = last r
|
|
|
113
|
first (BankersQueue _ (Cons x _) _ _) = Just x
|
|
|
114
|
|
|
|
115
|
-- O(1) amortized
|
|
|
116
|
last (BankersQueue _ f _ Nil) = last f
|
|
|
117
|
last (BankersQueue _ _ _ r) = first r
|
|
|
118
|
|
|
|
119
|
cons x q = enqueue x q
|
|
|
120
|
nil = BankersQueue 0 Nil 0 Nil
|
|
|
121
|
|
|
|
122
|
rest q | isEmpty q = nil
|
|
|
123
|
rest q =
|
|
|
124
|
case dequeue q of
|
|
|
125
|
Nothing -> nil
|
|
|
126
|
Just (_, q') -> q'
|
|
|
127
|
|
|
|
128
|
length (BankersQueue fs _ rs _) = fs + rs
|
|
|
129
|
|
|
|
130
|
isEmpty (BankersQueue _ Nil _ Nil) = True
|
|
|
131
|
isEmpty _ = False
|
|
|
132
|
|
|
|
133
|
-- examples
|
|
|
134
|
sl = fromList [1..10] :: List Integer
|
|
|
135
|
bq = fromList [1..10] :: BankersQueue Integer
|