competitive/data_structure/
doubly_linked_list.rs1#[derive(Debug, Clone)]
5pub struct DoublyLinkedList {
6 prev: Vec<usize>,
7 next: Vec<usize>,
8}
9
10impl DoublyLinkedList {
11 pub fn new(n: usize) -> Self {
12 Self {
13 prev: vec![usize::MAX; n],
14 next: vec![usize::MAX; n],
15 }
16 }
17
18 pub fn len(&self) -> usize {
19 self.prev.len()
20 }
21
22 pub fn is_empty(&self) -> bool {
23 self.len() == 0
24 }
25
26 pub fn prev(&self, index: usize) -> usize {
27 self.prev[index]
28 }
29
30 pub fn next(&self, index: usize) -> usize {
31 self.next[index]
32 }
33
34 pub fn link(&mut self, front: usize, back: usize) {
39 assert_ne!(front, back);
40 assert_eq!(self.next[front], usize::MAX);
41 assert_eq!(self.prev[back], usize::MAX);
42 self.next[front] = back;
43 self.prev[back] = front;
44 }
45
46 pub fn cut_before(&mut self, index: usize) -> usize {
47 let prev = self.prev[index];
48 if prev != usize::MAX {
49 self.next[prev] = usize::MAX;
50 self.prev[index] = usize::MAX;
51 }
52 prev
53 }
54
55 pub fn cut_after(&mut self, index: usize) -> usize {
56 let next = self.next[index];
57 if next != usize::MAX {
58 self.prev[next] = usize::MAX;
59 self.next[index] = usize::MAX;
60 }
61 next
62 }
63
64 pub fn detach(&mut self, index: usize) -> (usize, usize) {
65 let prev = self.cut_before(index);
66 let next = self.cut_after(index);
67 if prev != usize::MAX && next != usize::MAX {
68 self.link(prev, next);
69 }
70 (prev, next)
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77 use crate::tools::Xorshift;
78
79 #[test]
80 fn test_doubly_linked_list_random() {
81 const CASES: usize = 200;
82 const Q: usize = 200;
83
84 let mut rng = Xorshift::default();
85 for _ in 0..CASES {
86 let n = rng.random(0..=30);
87 let mut list = DoublyLinkedList::new(n);
88 let mut lists: Vec<Vec<_>> = (0..n).map(|i| vec![i]).collect();
89 let position = |lists: &[Vec<usize>], v| {
90 lists
91 .iter()
92 .enumerate()
93 .find_map(|(i, list)| list.iter().position(|&u| u == v).map(|j| (i, j)))
94 .unwrap()
95 };
96 assert_eq!(list.is_empty(), n == 0);
97
98 for _ in 0..Q {
99 if n == 0 {
100 continue;
101 }
102
103 match rng.random(0..4) {
104 0 if lists.len() >= 2 => {
105 let mut a = rng.random(0..lists.len());
106 let mut b = rng.random(0..lists.len() - 1);
107 if a <= b {
108 b += 1;
109 }
110 let front = *lists[a].last().unwrap();
111 let back = lists[b][0];
112 list.link(front, back);
113
114 let other = lists.remove(b);
115 if b < a {
116 a -= 1;
117 }
118 lists[a].extend(other);
119 }
120 1 => {
121 let v = rng.random(0..n);
122 let (i, j) = position(&lists, v);
123 let prev = if j == 0 { usize::MAX } else { lists[i][j - 1] };
124 assert_eq!(list.cut_before(v), prev);
125 if j != 0 {
126 let right = lists[i].split_off(j);
127 lists.push(right);
128 }
129 }
130 2 => {
131 let v = rng.random(0..n);
132 let (i, j) = position(&lists, v);
133 let next = if j + 1 == lists[i].len() {
134 usize::MAX
135 } else {
136 lists[i][j + 1]
137 };
138 assert_eq!(list.cut_after(v), next);
139 if j + 1 != lists[i].len() {
140 let right = lists[i].split_off(j + 1);
141 lists.push(right);
142 }
143 }
144 _ => {
145 let v = rng.random(0..n);
146 let (i, j) = position(&lists, v);
147 let prev = if j == 0 { usize::MAX } else { lists[i][j - 1] };
148 let next = if j + 1 == lists[i].len() {
149 usize::MAX
150 } else {
151 lists[i][j + 1]
152 };
153 assert_eq!(list.detach(v), (prev, next));
154 lists[i].remove(j);
155 if lists[i].is_empty() {
156 lists.swap_remove(i);
157 }
158 lists.push(vec![v]);
159 }
160 }
161
162 let mut prev = vec![usize::MAX; n];
163 let mut next = vec![usize::MAX; n];
164 for row in &lists {
165 for (i, &v) in row.iter().enumerate() {
166 if i != 0 {
167 prev[v] = row[i - 1];
168 }
169 if i + 1 != row.len() {
170 next[v] = row[i + 1];
171 }
172 }
173 }
174 for i in 0..n {
175 assert_eq!(list.prev(i), prev[i]);
176 assert_eq!(list.next(i), next[i]);
177 }
178 }
179 }
180 }
181}