exercism/zig/linked-list/linked_list.zig
2024-07-28 17:45:02 -04:00

97 lines
2.8 KiB
Zig

pub fn LinkedList(comptime T: type) type {
return struct {
// Please implement the doubly linked `Node` (replacing each `void`).
pub const Node = struct {
prev: ?*Node = null,
next: ?*Node = null,
data: T,
};
// Please implement the fields of the linked list (replacing each `void`).
first: ?*Node = null,
last: ?*Node = null,
len: usize = 0,
// Please implement the below methods.
// You need to add the parameters to each method.
pub fn push(self: *LinkedList(T), item: *Node) void {
defer self.len += 1;
if (self.len == 0) {
self.first = item;
} else {
self.last.?.next = item;
item.prev = self.last;
}
self.last = item;
}
pub fn pop(self: *LinkedList(T)) ?*Node {
defer self.len -= 1;
const last = self.last.?;
if (last.prev != null) {
self.last = last.prev;
self.last.?.next = null;
last.prev = null;
} else {
self.last = null;
self.first = null;
}
return last;
}
pub fn shift(self: *LinkedList(T)) ?*Node {
defer self.len -= 1;
const first = self.first.?;
if (first != self.last) {
self.first = first.next.?;
self.first.?.prev = null;
first.next = null;
} else {
self.first = null;
self.last = null;
}
return first;
}
pub fn unshift(self: *LinkedList(T), item: *Node) void {
defer self.len += 1;
if (self.len != 0) {
const first = self.first;
first.?.prev = item;
item.next = first;
} else {
self.last = item;
}
self.first = item;
}
pub fn delete(self: *LinkedList(T), item: *Node) void {
var n: ?*Node = self.first;
while (n != item and n != null) {
n = n.?.next;
}
if (n != null) {
defer self.len -= 1;
const prev = n.?.prev;
const next = n.?.next;
if (prev != null) {
prev.?.next = next;
}
if (next != null) {
next.?.prev = prev;
}
if (self.last == n) {
self.last = n.?.prev;
}
if (self.first == n) {
self.first = n.?.next;
}
n.?.prev = null;
n.?.next = null;
}
}
};
}