mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-25 14:06:29 +08:00
add zig codes for Section Queue and Deque (#291)
* add zig codes for Section 'Queue' * update zig codes for Section 'Queue' * update zig codes for Section 'Queue' * update zig codes for Section 'Queue' * update zig codes for Section 'Queue' and 'Deque' * update zig codes for Section 'Queue' and 'Deque' * update zig codes for Section 'Queue' and 'Deque'
This commit is contained in:
parent
0b5761eaf5
commit
d9f8c53e4a
7 changed files with 670 additions and 0 deletions
|
@ -160,6 +160,73 @@ pub fn build(b: *std.build.Builder) void {
|
|||
const run_step_array_stack = b.step("run_array_stack", "Run array_stack");
|
||||
run_step_array_stack.dependOn(&run_cmd_array_stack.step);
|
||||
|
||||
// Section: "Queue"
|
||||
// Source File: "chapter_stack_and_queue/queue.zig"
|
||||
// Run Command: zig build run_queue
|
||||
const exe_queue = b.addExecutable("queue", "chapter_stack_and_queue/queue.zig");
|
||||
exe_queue.addPackagePath("include", "include/include.zig");
|
||||
exe_queue.setTarget(target);
|
||||
exe_queue.setBuildMode(mode);
|
||||
exe_queue.install();
|
||||
const run_cmd_queue = exe_queue.run();
|
||||
run_cmd_queue.step.dependOn(b.getInstallStep());
|
||||
if (b.args) |args| run_cmd_queue.addArgs(args);
|
||||
const run_step_queue = b.step("run_queue", "Run queue");
|
||||
run_step_queue.dependOn(&run_cmd_queue.step);
|
||||
|
||||
// Source File: "chapter_stack_and_queue/array_queue.zig"
|
||||
// Run Command: zig build run_array_queue
|
||||
const exe_array_queue = b.addExecutable("array_queue", "chapter_stack_and_queue/array_queue.zig");
|
||||
exe_array_queue.addPackagePath("include", "include/include.zig");
|
||||
exe_array_queue.setTarget(target);
|
||||
exe_array_queue.setBuildMode(mode);
|
||||
exe_array_queue.install();
|
||||
const run_cmd_array_queue = exe_array_queue.run();
|
||||
run_cmd_array_queue.step.dependOn(b.getInstallStep());
|
||||
if (b.args) |args| run_cmd_array_queue.addArgs(args);
|
||||
const run_step_array_queue = b.step("run_array_queue", "Run array_queue");
|
||||
run_step_array_queue.dependOn(&run_cmd_array_queue.step);
|
||||
|
||||
// Source File: "chapter_stack_and_queue/linkedlist_queue.zig"
|
||||
// Run Command: zig build run_linkedlist_queue
|
||||
const exe_linkedlist_queue = b.addExecutable("linkedlist_queue", "chapter_stack_and_queue/linkedlist_queue.zig");
|
||||
exe_linkedlist_queue.addPackagePath("include", "include/include.zig");
|
||||
exe_linkedlist_queue.setTarget(target);
|
||||
exe_linkedlist_queue.setBuildMode(mode);
|
||||
exe_linkedlist_queue.install();
|
||||
const run_cmd_linkedlist_queue = exe_linkedlist_queue.run();
|
||||
run_cmd_linkedlist_queue.step.dependOn(b.getInstallStep());
|
||||
if (b.args) |args| run_cmd_linkedlist_queue.addArgs(args);
|
||||
const run_step_linkedlist_queue = b.step("run_linkedlist_queue", "Run linkedlist_queue");
|
||||
run_step_linkedlist_queue.dependOn(&run_cmd_linkedlist_queue.step);
|
||||
|
||||
// Section: "Deque"
|
||||
// Source File: "chapter_stack_and_queue/deque.zig"
|
||||
// Run Command: zig build run_deque
|
||||
const exe_deque = b.addExecutable("deque", "chapter_stack_and_queue/deque.zig");
|
||||
exe_deque.addPackagePath("include", "include/include.zig");
|
||||
exe_deque.setTarget(target);
|
||||
exe_deque.setBuildMode(mode);
|
||||
exe_deque.install();
|
||||
const run_cmd_deque = exe_deque.run();
|
||||
run_cmd_deque.step.dependOn(b.getInstallStep());
|
||||
if (b.args) |args| run_cmd_deque.addArgs(args);
|
||||
const run_step_deque = b.step("run_deque", "Run deque");
|
||||
run_step_deque.dependOn(&run_cmd_deque.step);
|
||||
|
||||
// Source File: "chapter_stack_and_queue/linkedlist_deque.zig"
|
||||
// Run Command: zig build run_linkedlist_deque
|
||||
const exe_linkedlist_deque = b.addExecutable("linkedlist_deque", "chapter_stack_and_queue/linkedlist_deque.zig");
|
||||
exe_linkedlist_deque.addPackagePath("include", "include/include.zig");
|
||||
exe_linkedlist_deque.setTarget(target);
|
||||
exe_linkedlist_deque.setBuildMode(mode);
|
||||
exe_linkedlist_deque.install();
|
||||
const run_cmd_linkedlist_deque = exe_linkedlist_deque.run();
|
||||
run_cmd_linkedlist_deque.step.dependOn(b.getInstallStep());
|
||||
if (b.args) |args| run_cmd_linkedlist_deque.addArgs(args);
|
||||
const run_step_linkedlist_deque = b.step("run_linkedlist_deque", "Run linkedlist_deque");
|
||||
run_step_linkedlist_deque.dependOn(&run_cmd_linkedlist_deque.step);
|
||||
|
||||
// Section: "Hash Map"
|
||||
// Source File: "chapter_hashing/hash_map.zig"
|
||||
// Run Command: zig build run_hash_map
|
||||
|
|
138
codes/zig/chapter_stack_and_queue/array_queue.zig
Normal file
138
codes/zig/chapter_stack_and_queue/array_queue.zig
Normal file
|
@ -0,0 +1,138 @@
|
|||
// File: array_queue.zig
|
||||
// Created Time: 2023-01-15
|
||||
// Author: sjinzh (sjinzh@gmail.com)
|
||||
|
||||
const std = @import("std");
|
||||
const inc = @import("include");
|
||||
|
||||
// 基于环形数组实现的队列
|
||||
pub fn ArrayQueue(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
nums: []T = undefined, // 用于存储队列元素的数组
|
||||
cap: usize = 0, // 队列容量
|
||||
front: usize = 0, // 头指针,指向队首
|
||||
rear: usize = 0, // 尾指针,指向队尾 + 1
|
||||
mem_arena: ?std.heap.ArenaAllocator = null,
|
||||
mem_allocator: std.mem.Allocator = undefined, // 内存分配器
|
||||
|
||||
// 构造函数(分配内存+初始化数组)
|
||||
pub fn init(self: *Self, allocator: std.mem.Allocator, cap: usize) !void {
|
||||
if (self.mem_arena == null) {
|
||||
self.mem_arena = std.heap.ArenaAllocator.init(allocator);
|
||||
self.mem_allocator = self.mem_arena.?.allocator();
|
||||
}
|
||||
self.cap = cap;
|
||||
self.nums = try self.mem_allocator.alloc(T, self.cap);
|
||||
std.mem.set(T, self.nums, @as(T, 0));
|
||||
}
|
||||
|
||||
// 析构函数(释放内存)
|
||||
pub fn deinit(self: *Self) void {
|
||||
if (self.mem_arena == null) return;
|
||||
self.mem_arena.?.deinit();
|
||||
}
|
||||
|
||||
// 获取队列的容量
|
||||
pub fn capacity(self: *Self) usize {
|
||||
return self.cap;
|
||||
}
|
||||
|
||||
// 获取队列的长度
|
||||
pub fn size(self: *Self) usize {
|
||||
// 由于将数组看作为环形,可能 rear < front ,因此需要取余数
|
||||
return (self.capacity() + self.rear - self.front) % self.capacity();
|
||||
}
|
||||
|
||||
// 判断队列是否为空
|
||||
pub fn isEmpty(self: *Self) bool {
|
||||
return self.rear == self.front;
|
||||
}
|
||||
|
||||
// 入队
|
||||
pub fn offer(self: *Self, num: T) !void {
|
||||
if (self.size() == self.capacity()) {
|
||||
std.debug.print("队列已满\n", .{});
|
||||
return;
|
||||
}
|
||||
// 尾结点后添加 num
|
||||
self.nums[self.rear] = num;
|
||||
// 尾指针向后移动一位,越过尾部后返回到数组头部
|
||||
self.rear = (self.rear + 1) % self.capacity();
|
||||
}
|
||||
|
||||
// 出队
|
||||
pub fn poll(self: *Self) T {
|
||||
var num = self.peek();
|
||||
// 队头指针向后移动一位,若越过尾部则返回到数组头部
|
||||
self.front = (self.front + 1) % self.capacity();
|
||||
return num;
|
||||
}
|
||||
|
||||
// 访问队首元素
|
||||
pub fn peek(self: *Self) T {
|
||||
if (self.isEmpty()) @panic("队列为空");
|
||||
return self.nums[self.front];
|
||||
}
|
||||
|
||||
// 返回数组
|
||||
pub fn toArray(self: *Self) ![]T {
|
||||
// 仅转换有效长度范围内的列表元素
|
||||
var res = try self.mem_allocator.alloc(T, self.size());
|
||||
std.mem.set(T, res, @as(T, 0));
|
||||
var i: usize = 0;
|
||||
var j: usize = self.front;
|
||||
while (i < self.size()) : ({ i += 1; j += 1; }) {
|
||||
res[i] = self.nums[j % self.capacity()];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Driver Code
|
||||
pub fn main() !void {
|
||||
// 初始化队列
|
||||
var capacity: usize = 10;
|
||||
var queue = ArrayQueue(i32){};
|
||||
try queue.init(std.heap.page_allocator, capacity);
|
||||
defer queue.deinit();
|
||||
|
||||
// 元素入队
|
||||
try queue.offer(1);
|
||||
try queue.offer(3);
|
||||
try queue.offer(2);
|
||||
try queue.offer(5);
|
||||
try queue.offer(4);
|
||||
std.debug.print("队列 queue = ", .{});
|
||||
inc.PrintUtil.printArray(i32, try queue.toArray());
|
||||
|
||||
// 访问队首元素
|
||||
var peek = queue.peek();
|
||||
std.debug.print("\n队首元素 peek = {}", .{peek});
|
||||
|
||||
// 元素出队
|
||||
var poll = queue.poll();
|
||||
std.debug.print("\n出队元素 poll = {},出队后 queue = ", .{poll});
|
||||
inc.PrintUtil.printArray(i32, try queue.toArray());
|
||||
|
||||
// 获取队列的长度
|
||||
var size = queue.size();
|
||||
std.debug.print("\n队列长度 size = {}", .{size});
|
||||
|
||||
// 判断队列是否为空
|
||||
var isEmpty = queue.isEmpty();
|
||||
std.debug.print("\n队列是否为空 = {}", .{isEmpty});
|
||||
|
||||
// 测试环形数组
|
||||
var i: i32 = 0;
|
||||
while (i < 10) : (i += 1) {
|
||||
try queue.offer(i);
|
||||
_ = queue.poll();
|
||||
std.debug.print("\n第 {} 轮入队 + 出队后 queue = ", .{i});
|
||||
inc.PrintUtil.printArray(i32, try queue.toArray());
|
||||
}
|
||||
|
||||
_ = try std.io.getStdIn().reader().readByte();
|
||||
}
|
51
codes/zig/chapter_stack_and_queue/deque.zig
Normal file
51
codes/zig/chapter_stack_and_queue/deque.zig
Normal file
|
@ -0,0 +1,51 @@
|
|||
// File: deque.zig
|
||||
// Created Time: 2023-01-15
|
||||
// Author: sjinzh (sjinzh@gmail.com)
|
||||
|
||||
const std = @import("std");
|
||||
const inc = @import("include");
|
||||
|
||||
// Driver Code
|
||||
pub fn main() !void {
|
||||
// 初始化双向队列
|
||||
const L = std.TailQueue(i32);
|
||||
var deque = L{};
|
||||
|
||||
// 元素入队
|
||||
var node1 = L.Node{ .data = 2 };
|
||||
var node2 = L.Node{ .data = 5 };
|
||||
var node3 = L.Node{ .data = 4 };
|
||||
var node4 = L.Node{ .data = 3 };
|
||||
var node5 = L.Node{ .data = 1 };
|
||||
deque.append(&node1);
|
||||
deque.append(&node2);
|
||||
deque.append(&node3);
|
||||
deque.prepend(&node4);
|
||||
deque.prepend(&node5);
|
||||
std.debug.print("双向队列 deque = ", .{});
|
||||
inc.PrintUtil.printQueue(i32, deque);
|
||||
|
||||
// 访问元素
|
||||
var peekFirst = deque.first.?.data;
|
||||
std.debug.print("\n队首元素 peekFirst = {}", .{peekFirst});
|
||||
var peekLast = deque.last.?.data;
|
||||
std.debug.print("\n队首元素 peekLast = {}", .{peekLast});
|
||||
|
||||
// 元素出队
|
||||
var pollFirst = deque.popFirst().?.data;
|
||||
std.debug.print("\n队首出队元素 pollFirst = {},队首出队后 deque = ", .{pollFirst});
|
||||
inc.PrintUtil.printQueue(i32, deque);
|
||||
var pollLast = deque.pop().?.data;
|
||||
std.debug.print("\n队尾出队元素 pollLast = {},队尾出队后 deque = ", .{pollLast});
|
||||
inc.PrintUtil.printQueue(i32, deque);
|
||||
|
||||
// 获取双向队列的长度
|
||||
var size = deque.len;
|
||||
std.debug.print("\n双向队列长度 size = {}", .{size});
|
||||
|
||||
// 判断队列是否为空
|
||||
var isEmpty = if (deque.len == 0) true else false;
|
||||
std.debug.print("\n双向队列是否为空 = {}", .{isEmpty});
|
||||
|
||||
_ = try std.io.getStdIn().reader().readByte();
|
||||
}
|
229
codes/zig/chapter_stack_and_queue/linkedlist_deque.zig
Normal file
229
codes/zig/chapter_stack_and_queue/linkedlist_deque.zig
Normal file
|
@ -0,0 +1,229 @@
|
|||
// File: linkedlist_deque.zig
|
||||
// Created Time: 2023-01-15
|
||||
// Author: sjinzh (sjinzh@gmail.com)
|
||||
|
||||
const std = @import("std");
|
||||
const inc = @import("include");
|
||||
|
||||
// 双向链表结点
|
||||
pub fn ListNode(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
val: T = undefined, // 结点值
|
||||
next: ?*Self = null, // 后继结点引用(指针)
|
||||
prev: ?*Self = null, // 前驱结点引用(指针)
|
||||
|
||||
// Initialize a list node with specific value
|
||||
pub fn init(self: *Self, x: i32) void {
|
||||
self.val = x;
|
||||
self.next = null;
|
||||
self.prev = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 基于双向链表实现的双向队列
|
||||
pub fn LinkedListDeque(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
front: ?*ListNode(T) = null, // 头结点 front
|
||||
rear: ?*ListNode(T) = null, // 尾结点 rear
|
||||
deqSize: usize = 0, // 双向队列的长度
|
||||
mem_arena: ?std.heap.ArenaAllocator = null,
|
||||
mem_allocator: std.mem.Allocator = undefined, // 内存分配器
|
||||
|
||||
// 构造函数(分配内存+初始化队列)
|
||||
pub fn init(self: *Self, allocator: std.mem.Allocator) !void {
|
||||
if (self.mem_arena == null) {
|
||||
self.mem_arena = std.heap.ArenaAllocator.init(allocator);
|
||||
self.mem_allocator = self.mem_arena.?.allocator();
|
||||
}
|
||||
self.front = null;
|
||||
self.rear = null;
|
||||
self.deqSize = 0;
|
||||
}
|
||||
|
||||
// 析构函数(释放内存)
|
||||
pub fn deinit(self: *Self) void {
|
||||
if (self.mem_arena == null) return;
|
||||
self.mem_arena.?.deinit();
|
||||
}
|
||||
|
||||
// 获取双向队列的长度
|
||||
pub fn size(self: *Self) usize {
|
||||
return self.deqSize;
|
||||
}
|
||||
|
||||
// 判断双向队列是否为空
|
||||
pub fn isEmpty(self: *Self) bool {
|
||||
return self.size() == 0;
|
||||
}
|
||||
|
||||
// 入队操作
|
||||
pub fn offer(self: *Self, num: T, isFront: bool) !void {
|
||||
var node = try self.mem_allocator.create(ListNode(T));
|
||||
node.init(num);
|
||||
// 若链表为空,则令 front, rear 都指向 node
|
||||
if (self.isEmpty()) {
|
||||
self.front = node;
|
||||
self.rear = node;
|
||||
// 队首入队操作
|
||||
} else if (isFront) {
|
||||
// 将 node 添加至链表头部
|
||||
self.front.?.prev = node;
|
||||
node.next = self.front;
|
||||
self.front = node; // 更新头结点
|
||||
// 队尾入队操作
|
||||
} else {
|
||||
// 将 node 添加至链表尾部
|
||||
self.rear.?.next = node;
|
||||
node.prev = self.rear;
|
||||
self.rear = node; // 更新尾结点
|
||||
}
|
||||
self.deqSize += 1; // 更新队列长度
|
||||
}
|
||||
|
||||
// 队首入队
|
||||
pub fn offerFirst(self: *Self, num: T) !void {
|
||||
try self.offer(num, true);
|
||||
}
|
||||
|
||||
// 队尾入队
|
||||
pub fn offerLast(self: *Self, num: T) !void {
|
||||
try self.offer(num, false);
|
||||
}
|
||||
|
||||
// 出队操作
|
||||
pub fn poll(self: *Self, isFront: bool) T {
|
||||
if (self.isEmpty()) @panic("双向队列为空");
|
||||
var val: T = undefined;
|
||||
// 队首出队操作
|
||||
if (isFront) {
|
||||
val = self.front.?.val; // 暂存头结点值
|
||||
// 删除头结点
|
||||
var fNext = self.front.?.next;
|
||||
if (fNext != null) {
|
||||
fNext.?.prev = null;
|
||||
self.front.?.next = null;
|
||||
}
|
||||
self.front = fNext; // 更新头结点
|
||||
// 队尾出队操作
|
||||
} else {
|
||||
val = self.rear.?.val; // 暂存尾结点值
|
||||
// 删除尾结点
|
||||
var rPrev = self.rear.?.prev;
|
||||
if (rPrev != null) {
|
||||
rPrev.?.next = null;
|
||||
self.rear.?.prev = null;
|
||||
}
|
||||
self.rear = rPrev; // 更新尾结点
|
||||
}
|
||||
self.deqSize -= 1; // 更新队列长度
|
||||
return val;
|
||||
}
|
||||
|
||||
// 队首出队
|
||||
pub fn pollFirst(self: *Self) T {
|
||||
return self.poll(true);
|
||||
}
|
||||
|
||||
// 队尾出队
|
||||
pub fn pollLast(self: *Self) T {
|
||||
return self.poll(false);
|
||||
}
|
||||
|
||||
// 访问队首元素
|
||||
pub fn peekFirst(self: *Self) T {
|
||||
if (self.isEmpty()) @panic("双向队列为空");
|
||||
return self.front.?.val;
|
||||
}
|
||||
|
||||
// 访问队尾元素
|
||||
pub fn peekLast(self: *Self) T {
|
||||
if (self.isEmpty()) @panic("双向队列为空");
|
||||
return self.rear.?.val;
|
||||
}
|
||||
|
||||
// 将链表转换为数组
|
||||
pub fn toArray(self: *Self) ![]T {
|
||||
var node = self.front;
|
||||
var res = try self.mem_allocator.alloc(T, self.size());
|
||||
std.mem.set(T, res, @as(T, 0));
|
||||
var i: usize = 0;
|
||||
while (i < res.len) : (i += 1) {
|
||||
res[i] = node.?.val;
|
||||
node = node.?.next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// 打印双向队列
|
||||
pub fn print(self: *Self) !void {
|
||||
var nums = try self.toArray();
|
||||
std.debug.print("[", .{});
|
||||
if (nums.len > 0) {
|
||||
for (nums) |num, j| {
|
||||
std.debug.print("{}{s}", .{num, if (j == nums.len - 1) "]" else " <-> " });
|
||||
}
|
||||
} else {
|
||||
std.debug.print("]", .{});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Driver Code
|
||||
pub fn main() !void {
|
||||
// 初始化双向队列
|
||||
var deque = LinkedListDeque(i32){};
|
||||
try deque.init(std.heap.page_allocator);
|
||||
defer deque.deinit();
|
||||
std.debug.print("初始化空队列\n", .{});
|
||||
try deque.print();
|
||||
|
||||
var nums = [_]i32{ 1, 2, 3}; // 测试数据
|
||||
|
||||
// 队尾入队
|
||||
for (nums) |num| {
|
||||
try deque.offerLast(num);
|
||||
std.debug.print("\n元素 {} 队尾入队后,队列为\n", .{num});
|
||||
try deque.print();
|
||||
}
|
||||
// 获取队尾元素
|
||||
var last = deque.peekLast();
|
||||
std.debug.print("\n队尾元素为 {}", .{last});
|
||||
// 队尾出队
|
||||
while (!deque.isEmpty()) {
|
||||
last = deque.pollLast();
|
||||
std.debug.print("\n队尾出队元素为 {} ,队列为\n", .{last});
|
||||
try deque.print();
|
||||
}
|
||||
|
||||
// 队首入队
|
||||
for (nums) |num| {
|
||||
try deque.offerFirst(num);
|
||||
std.debug.print("\n元素 {} 队首入队后,队列为\n", .{num});
|
||||
try deque.print();
|
||||
}
|
||||
// 获取队首元素
|
||||
var first = deque.peekFirst();
|
||||
std.debug.print("\n队首元素为 {}", .{first});
|
||||
// 队首出队
|
||||
while (!deque.isEmpty()) {
|
||||
first = deque.pollFirst();
|
||||
std.debug.print("\n队首出队元素为 {} ,队列为\n", .{first});
|
||||
try deque.print();
|
||||
}
|
||||
|
||||
// 获取队列的长度
|
||||
var size = deque.size();
|
||||
std.debug.print("\n队列长度 size = {}", .{size});
|
||||
|
||||
// 判断双向队列是否为空
|
||||
var isEmpty = deque.isEmpty();
|
||||
std.debug.print("\n双向队列是否为空 = {}", .{isEmpty});
|
||||
|
||||
_ = try std.io.getStdIn().reader().readByte();
|
||||
}
|
127
codes/zig/chapter_stack_and_queue/linkedlist_queue.zig
Normal file
127
codes/zig/chapter_stack_and_queue/linkedlist_queue.zig
Normal file
|
@ -0,0 +1,127 @@
|
|||
// File: linkedlist_queue.zig
|
||||
// Created Time: 2023-01-15
|
||||
// Author: sjinzh (sjinzh@gmail.com)
|
||||
|
||||
const std = @import("std");
|
||||
const inc = @import("include");
|
||||
|
||||
// 基于链表实现的队列
|
||||
pub fn LinkedListQueue(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
front: ?*inc.ListNode(T) = null, // 头结点 front
|
||||
rear: ?*inc.ListNode(T) = null, // 尾结点 rear
|
||||
queSize: usize = 0, // 队列的长度
|
||||
mem_arena: ?std.heap.ArenaAllocator = null,
|
||||
mem_allocator: std.mem.Allocator = undefined, // 内存分配器
|
||||
|
||||
// 构造函数(分配内存+初始化队列)
|
||||
pub fn init(self: *Self, allocator: std.mem.Allocator) !void {
|
||||
if (self.mem_arena == null) {
|
||||
self.mem_arena = std.heap.ArenaAllocator.init(allocator);
|
||||
self.mem_allocator = self.mem_arena.?.allocator();
|
||||
}
|
||||
self.front = null;
|
||||
self.rear = null;
|
||||
self.queSize = 0;
|
||||
}
|
||||
|
||||
// 析构函数(释放内存)
|
||||
pub fn deinit(self: *Self) void {
|
||||
if (self.mem_arena == null) return;
|
||||
self.mem_arena.?.deinit();
|
||||
}
|
||||
|
||||
// 获取队列的长度
|
||||
pub fn size(self: *Self) usize {
|
||||
return self.queSize;
|
||||
}
|
||||
|
||||
// 判断队列是否为空
|
||||
pub fn isEmpty(self: *Self) bool {
|
||||
return self.size() == 0;
|
||||
}
|
||||
|
||||
// 访问队首元素
|
||||
pub fn peek(self: *Self) T {
|
||||
if (self.size() == 0) @panic("队列为空");
|
||||
return self.front.?.val;
|
||||
}
|
||||
|
||||
// 入队
|
||||
pub fn offer(self: *Self, num: T) !void {
|
||||
// 尾结点后添加 num
|
||||
var node = try self.mem_allocator.create(inc.ListNode(T));
|
||||
node.init(num);
|
||||
// 如果队列为空,则令头、尾结点都指向该结点
|
||||
if (self.front == null) {
|
||||
self.front = node;
|
||||
self.rear = node;
|
||||
// 如果队列不为空,则将该结点添加到尾结点后
|
||||
} else {
|
||||
self.rear.?.next = node;
|
||||
self.rear = node;
|
||||
}
|
||||
self.queSize += 1;
|
||||
}
|
||||
|
||||
// 出队
|
||||
pub fn poll(self: *Self) T {
|
||||
var num = self.peek();
|
||||
// 删除头结点
|
||||
self.front = self.front.?.next;
|
||||
self.queSize -= 1;
|
||||
return num;
|
||||
}
|
||||
|
||||
// 将链表转换为数组
|
||||
pub fn toArray(self: *Self) ![]T {
|
||||
var node = self.front;
|
||||
var res = try self.mem_allocator.alloc(T, self.size());
|
||||
std.mem.set(T, res, @as(T, 0));
|
||||
var i: usize = 0;
|
||||
while (i < res.len) : (i += 1) {
|
||||
res[i] = node.?.val;
|
||||
node = node.?.next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Driver Code
|
||||
pub fn main() !void {
|
||||
// 初始化队列
|
||||
var queue = LinkedListQueue(i32){};
|
||||
try queue.init(std.heap.page_allocator);
|
||||
defer queue.deinit();
|
||||
|
||||
// 元素入队
|
||||
try queue.offer(1);
|
||||
try queue.offer(3);
|
||||
try queue.offer(2);
|
||||
try queue.offer(5);
|
||||
try queue.offer(4);
|
||||
std.debug.print("队列 queue = ", .{});
|
||||
inc.PrintUtil.printArray(i32, try queue.toArray());
|
||||
|
||||
// 访问队首元素
|
||||
var peek = queue.peek();
|
||||
std.debug.print("\n队首元素 peek = {}", .{peek});
|
||||
|
||||
// 元素出队
|
||||
var poll = queue.poll();
|
||||
std.debug.print("\n出队元素 poll = {},出队后 queue = ", .{poll});
|
||||
inc.PrintUtil.printArray(i32, try queue.toArray());
|
||||
|
||||
// 获取队列的长度
|
||||
var size = queue.size();
|
||||
std.debug.print("\n队列长度 size = {}", .{size});
|
||||
|
||||
// 判断队列是否为空
|
||||
var isEmpty = queue.isEmpty();
|
||||
std.debug.print("\n队列是否为空 = {}", .{isEmpty});
|
||||
|
||||
_ = try std.io.getStdIn().reader().readByte();
|
||||
}
|
46
codes/zig/chapter_stack_and_queue/queue.zig
Normal file
46
codes/zig/chapter_stack_and_queue/queue.zig
Normal file
|
@ -0,0 +1,46 @@
|
|||
// File: queue.zig
|
||||
// Created Time: 2023-01-15
|
||||
// Author: sjinzh (sjinzh@gmail.com)
|
||||
|
||||
const std = @import("std");
|
||||
const inc = @import("include");
|
||||
|
||||
// Driver Code
|
||||
pub fn main() !void {
|
||||
// 初始化队列
|
||||
const L = std.TailQueue(i32);
|
||||
var queue = L{};
|
||||
|
||||
// 元素入队
|
||||
var node1 = L.Node{ .data = 1 };
|
||||
var node2 = L.Node{ .data = 3 };
|
||||
var node3 = L.Node{ .data = 2 };
|
||||
var node4 = L.Node{ .data = 5 };
|
||||
var node5 = L.Node{ .data = 4 };
|
||||
queue.append(&node1);
|
||||
queue.append(&node2);
|
||||
queue.append(&node3);
|
||||
queue.append(&node4);
|
||||
queue.append(&node5);
|
||||
std.debug.print("队列 queue = ", .{});
|
||||
inc.PrintUtil.printQueue(i32, queue);
|
||||
|
||||
// 访问队首元素
|
||||
var front = queue.first.?.data;
|
||||
std.debug.print("\n队首元素 front = {}", .{front});
|
||||
|
||||
// 元素出队
|
||||
front = queue.popFirst().?.data;
|
||||
std.debug.print("\n出队元素 front = {},出队后 queue = ", .{front});
|
||||
inc.PrintUtil.printQueue(i32, queue);
|
||||
|
||||
// 获取队列的长度
|
||||
var size = queue.len;
|
||||
std.debug.print("\n队列长度 size = {}", .{size});
|
||||
|
||||
// 判断队列是否为空
|
||||
var empty = if (queue.len == 0) true else false;
|
||||
std.debug.print("\n队列是否为空 = {}", .{empty});
|
||||
|
||||
_ = try std.io.getStdIn().reader().readByte();
|
||||
}
|
|
@ -48,6 +48,18 @@ pub fn printLinkedList(comptime T: type, node: ?*ListNode(T)) !void {
|
|||
}
|
||||
}
|
||||
|
||||
// Print a queue or deque
|
||||
pub fn printQueue(comptime T: type, queue: std.TailQueue(T)) void {
|
||||
var node = queue.first;
|
||||
std.debug.print("[", .{});
|
||||
var i: i32 = 0;
|
||||
while (node != null) : (i += 1) {
|
||||
var data = node.?.data;
|
||||
std.debug.print("{}{s}", .{data, if (i == queue.len - 1) "]" else ", " });
|
||||
node = node.?.next;
|
||||
}
|
||||
}
|
||||
|
||||
// Print a HashMap
|
||||
pub fn printHashMap(comptime TKey: type, comptime TValue: type, map: std.AutoHashMap(TKey, TValue)) void {
|
||||
var it = map.iterator();
|
||||
|
|
Loading…
Reference in a new issue