PY/JS/JAVA/GO四语言对照|用"中医哲学"重构数据结构: "单链表"秒变“药材灵气通道”(可白嫖|附截图|最小原型)
⚡️ 兄弟姐妹们,你们缺的不是教程,是能跑通的实战!
💪这篇绝对是干货(下文有代码截图👇👇),赶紧点赞收藏,源码打包带走✨✨
✅✅链表手把手教程文章铺垫盖地,相信你们也看了很多也学会了,这里主要讲理念+实战🎈🎈
别人讲单链表还在用StudentNode,怪蜀黎直接上《GMP药材批次管理》——
10年ERP老兵+7年中医修为+其他技能树,给你整4语言对照的合规原型:
- Python:轻灵如针灸,107行搞定药材流转
- Java:稳重如老药工,严苛类型校验防呆设计
- Go:并发如抓药机,协程级性能碾压传统仓储
- JS:灵动如仙丹,前后端通吃还能可视化药柜
## 🌿 这玩意多硬核?
✅ 严格模拟**先进先出**(药监局GMP核心要求)
✅ 智能跳过**零库存批次**(防止空指针异常如防止抓错药)
✅ 批次消耗**实时追踪**(随时生成审计追踪报告)
✅ 4语言**同一算法不同实现**(学数据结构顺带练跨界)
🤯 单链表是个啥?怪蜀黎用中医给你比喻!
官方说法:单链表是线性表的数据结构,通过指针连接节点
怪蜀黎的说法:单链表就是中药房的药材流水账!注入理解灵魂后,这回简单多了是吧!💯💯
头节点(head)= 药柜最左边的当归抽屉(第一个批次)next指针= 药工的手(顺着抽屉一个个往后抓药)节点耗尽= 抽屉抓空了就拆下一个批次的包装(指针后移)
🌪️ 为什么不用数组?
数组像预制板西药盒——大小固定,塞不进一根大人参!
单链表像中药小抽屉——随用随开,来多少药材扩多少抽屉!
💡 怪蜀黎的顿悟时刻:
当年在药库看师傅抓药:“先进来的药材先抓,抓完一批再开下一批”(准确的说应该先抓批次和生产日期更早的这部分,防止时间存放太长变质,当然陈皮这些例外,越陈越好🎉🎉)
这TM不就是单链表的FIFO(先进先出)吗?!
所以怪蜀黎直接把BatchNode写成药材批次节点!
废话不多说直接上四语言代码,注释都写好了💪💪(注释代表怪蜀黎4种技能树):
# ==================== 财务单链模块 ====================
# 单向喜钱通道 # 资金只能向前流动的量子管道 ➡️
# ⚠️ERP_冷溪虎山:管道堵塞会导致嘿钱倒灌
class BatchNode:
"""库存批次节点"""
def __init__(self, batch_id, herb_name, inbound_date, quantity):
self.batch_id = batch_id # 批次ID
self.herb_name = herb_name # 药材名称
self.inbound_date = inbound_date # 入库日期(字符串格式"YYYY-MM-DD")
self.quantity = quantity # 剩余数量
self.next = None # 下一个批次指针
class HerbInventory:
def __init__(self):
self.head = None # 链表头节点(最早入库的批次)
# 新批次入库(添加到链表尾部)
def add_batch(self, batch_id, herb_name, inbound_date, quantity):
new_node = BatchNode(batch_id, herb_name, inbound_date, quantity)
if not self.head: # 空链表情况
self.head = new_node
return
current = self.head
while current.next: # 遍历到最后一个节点
current = current.next
current.next = new_node # 新批次添加到尾部
# 药材出库(从最早批次开始消耗)
def dispense_herb(self, herb_name, required_quantity):
if not self.head:
print(f"错误:库存中没有{herb_name}的任何批次")
return False
# 特殊情况:头节点就是目标药材且数量足够
if (self.head.herb_name == herb_name and
self.head.quantity >= required_quantity):
self.head.quantity -= required_quantity
print(f"出库成功:从批次{self.head.batch_id}消耗{required_quantity}{herb_name}")
if self.head.quantity == 0: # 该批次已耗尽
self.head = self.head.next
return True
# 一般情况:需要遍历链表
prev = None
current = self.head
while current:
if current.herb_name == herb_name:
if current.quantity >= required_quantity:
current.quantity -= required_quantity
print(f"出库成功:从批次{current.batch_id}消耗{required_quantity}{herb_name}")
if current.quantity == 0: # 该批次已耗尽
if prev: # 不是头节点
prev.next = current.next
else: # 是头节点
self.head = current.next
return True
else:
# 当前批次数量不足,尝试合并后续批次
remaining_need = required_quantity - current.quantity
if self._merge_subsequent_batches(current, herb_name, remaining_need):
return True
else:
print(f"错误:库存不足,无法满足{required_quantity}{herb_name}的需求")
return False
prev = current
current = current.next
print(f"错误:库存中没有{herb_name}的批次")
return False
# 辅助方法:合并后续同种药材批次
def _merge_subsequent_batches(self, start_node, herb_name, remaining_need):
current = start_node.next
while current and remaining_need > 0:
if current.herb_name == herb_name:
if current.quantity >= remaining_need:
current.quantity -= remaining_need
print(f"出库成功:从批次{current.batch_id}消耗{remaining_need}{herb_name}")
if current.quantity == 0: # 该批次已耗尽
start_node.next = current.next
remaining_need = 0
return True
else:
remaining_need -= current.quantity
start_node.next = current.next # 跳过已耗尽批次
current = start_node.next
else:
current = current.next
return remaining_need == 0
# 打印当前库存状态(按入库顺序)
def print_inventory(self):
if not self.head:
print("库存为空")
return
print("当前库存批次(按入库顺序):")
current = self.head
while current:
print(f"批次ID: {current.batch_id}, 药材: {current.herb_name}, "
f"入库日期: {current.inbound_date}, 剩余数量: {current.quantity}")
current = current.next
# ==================== 使用方法 ====================
if __name__ == "__main__":
warehouse = HerbInventory()
# 入库操作(按时间顺序,批号优先测试,暂不考虑产地,规格及其他信息)
warehouse.add_batch("Lot-d2025001", "当归", "2025-01-15", 500)
warehouse.add_batch("Lot-h2025002", "黄芪", "2025-02-20", 250)
warehouse.add_batch("Lot-x2025003", "西洋参", "2025-03-10", 200)
warehouse.add_batch("Lot-r2025004", "人参", "2025-04-05", 100)
print("\n🚀初始库存状态,单位:克")
warehouse.print_inventory()
# 抓药操作
print("\n--- 抓药操作1: 从当归批次消耗100克 ---")
warehouse.dispense_herb("当归", 100) # 500-100
print("--- 抓药操作2: 从当归批次消耗150克 ---")
warehouse.dispense_herb("黄芪", 150) # 250-150
print("--- 抓药操作3: 从黄芪批次消耗60克 ---")
warehouse.dispense_herb("西洋参", 60) # 200-60
print("--- 抓药操作4: 从人参批次消耗30克 ---")
warehouse.dispense_herb("人参", 30) # 100-30
print("\n🧭最终库存状态,单位:克")
warehouse.print_inventory()
Python注意缩进💎💎
[nodejs---------------------------------------------------------------------------------------------]
// ==================== 中药单链模块 ====================
// 单向药性传导 // 灵气只能顺流而下的仙脉 🌊
// ⚠️虎山老药师:仙脉逆流会引发丹炉爆炸
// 定义库存批次节点
class BatchNode {
constructor(batch_id, herb_name, inbound_date, quantity) {
this.batch_id = batch_id; // 批次ID
this.herb_name = herb_name; // 药材名称
this.inbound_date = inbound_date; // 入库日期(字符串格式"YYYY-MM-DD")
this.quantity = quantity; // 剩余数量
this.next = null; // 下一个批次指针
}
}
// 定义药材库存类
class HerbInventory {
constructor() {
this.head = null; // 链表头节点(最早入库的批次)
}
// 新批次入库(添加到链表尾部)
addBatch(batch_id, herb_name, inbound_date, quantity) {
const newNode = new BatchNode(batch_id, herb_name, inbound_date, quantity);
if (!this.head) { // 空链表情况
this.head = newNode;
return;
}
let current = this.head;
while (current.next) { // 遍历到最后一个节点
current = current.next;
}
current.next = newNode; // 新批次添加到尾部
}
// 药材出库(从最早批次开始消耗)
dispenseHerb(herb_name, required_quantity) {
if (!this.head) {
console.log(`错误:库存中没有${herb_name}的任何批次`);
return false;
}
// 特殊情况:头节点就是目标药材且数量足够
if (this.head.herb_name === herb_name && this.head.quantity >= required_quantity) {
this.head.quantity -= required_quantity;
console.log(`出库成功:从批次${this.head.batch_id}消耗${required_quantity}${herb_name}`);
if (this.head.quantity === 0) { // 该批次已耗尽
this.head = this.head.next;
}
return true;
}
// 一般情况:需要遍历链表
let prev = null;
let current = this.head;
while (current) {
if (current.herb_name === herb_name) {
if (current.quantity >= required_quantity) {
current.quantity -= required_quantity;
console.log(`出库成功:从批次${current.batch_id}消耗${required_quantity}${herb_name}`);
if (current.quantity === 0) { // 该批次已耗尽
if (prev) { // 不是头节点
prev.next = current.next;
} else { // 是头节点
this.head = current.next;
}
}
return true;
} else {
// 当前批次数量不足,尝试合并后续批次
const remainingNeed = required_quantity - current.quantity;
if (this._mergeSubsequentBatches(current, herb_name, remainingNeed)) {
return true;
} else {
console.log(`错误:库存不足,无法满足${required_quantity}${herb_name}的需求`);
return false;
}
}
}
prev = current;
current = current.next;
}
console.log(`错误:库存中没有${herb_name}的批次`);
return false;
}
// 辅助方法:合并后续同种药材批次
_mergeSubsequentBatches(startNode, herb_name, remainingNeed) {
let current = startNode.next;
while (current && remainingNeed > 0) {
if (current.herb_name === herb_name) {
if (current.quantity >= remainingNeed) {
current.quantity -= remainingNeed;
console.log(`出库成功:从批次${current.batch_id}消耗${remainingNeed}${herb_name}`);
if (current.quantity === 0) { // 该批次已耗尽
startNode.next = current.next;
}
remainingNeed = 0;
return true;
} else {
remainingNeed -= current.quantity;
startNode.next = current.next; // 跳过已耗尽批次
current = startNode.next;
}
} else {
current = current.next;
}
}
return remainingNeed === 0;
}
// 打印当前库存状态(按入库顺序)
printInventory() {
if (!this.head) {
console.log("库存为空");
return;
}
console.log("当前库存批次(按入库顺序):");
let current = this.head;
while (current) {
console.log(`批次ID: ${current.batch_id}, 药材: ${current.herb_name}, ` +
`入库日期: ${current.inbound_date}, 剩余数量: ${current.quantity}`);
current = current.next;
}
}
}
// ==================== 使用方法 ====================
const warehouse = new HerbInventory();
// 入库操作(按时间顺序,批号优先测试,暂不考虑产地,规格及其他信息)
warehouse.addBatch("Lot-d2025001", "当归", "2025-01-15", 500);
warehouse.addBatch("Lot-h2025002", "黄芪", "2025-02-20", 250);
warehouse.addBatch("Lot-x2025003", "西洋参", "2025-03-10", 200);
warehouse.addBatch("Lot-r2025004", "人参", "2025-04-05", 100);
console.log("\n🚀初始库存状态,单位:克");
warehouse.printInventory();
// 抓药操作
console.log("\n--- 抓药操作1: 从当归批次消耗100克 ---");
warehouse.dispenseHerb("当归", 100); // 500-100
console.log("--- 抓药操作2: 从当归批次消耗150克 ---");
warehouse.dispenseHerb("黄芪", 150); // 250-150
console.log("--- 抓药操作3: 从黄芪批次消耗60克 ---");
warehouse.dispenseHerb("西洋参", 60); // 200-60
console.log("--- 抓药操作4: 从人参批次消耗30克 ---");
warehouse.dispenseHerb("人参", 30); // 100-30
console.log("\n🧭最终库存状态,单位:克");
warehouse.printInventory();
[Go--------------------------------------------------------------------------------------------]
package main
import "fmt"
// ==================== 仓储单链模块 ====================
// 单向走斯路径 // 货品只能单向流动的量子隧道 🚇
// ⚠️冷溪物流:隧道坍塌会导致货物堆积
// 定义库存批次节点
type BatchNode struct {
batch_id string // 批次ID
herb_name string // 药材名称
inbound_date string // 入库日期(字符串格式"YYYY-MM-DD")
quantity int // 剩余数量
next *BatchNode // 下一个批次指针
}
// 定义药材库存类
type HerbInventory struct {
head *BatchNode // 链表头节点(最早入库的批次)
}
// 新批次入库(添加到链表尾部)
func (hi *HerbInventory) addBatch(batch_id, herb_name, inbound_date string, quantity int) {
newNode := &BatchNode{batch_id: batch_id, herb_name: herb_name, inbound_date: inbound_date, quantity: quantity, next: nil}
if hi.head == nil { // 空链表情况
hi.head = newNode
return
}
current := hi.head
for current.next != nil { // 遍历到最后一个节点
current = current.next
}
current.next = newNode // 新批次添加到尾部
}
// 药材出库(从最早批次开始消耗)
func (hi *HerbInventory) dispenseHerb(herb_name string, required_quantity int) bool {
if hi.head == nil {
fmt.Printf("错误:库存中没有%s的任何批次\n", herb_name)
return false
}
// 特殊情况:头节点就是目标药材且数量足够
if hi.head.herb_name == herb_name && hi.head.quantity >= required_quantity {
hi.head.quantity -= required_quantity
fmt.Printf("出库成功:从批次%s消耗%d%s\n", hi.head.batch_id, required_quantity, herb_name)
if hi.head.quantity == 0 { // 该批次已耗尽
hi.head = hi.head.next
}
return true
}
// 一般情况:需要遍历链表
var prev *BatchNode = nil
current := hi.head
for current != nil {
if current.herb_name == herb_name {
if current.quantity >= required_quantity {
current.quantity -= required_quantity
fmt.Printf("出库成功:从批次%s消耗%d%s\n", current.batch_id, required_quantity, herb_name)
if current.quantity == 0 { // 该批次已耗尽
if prev != nil { // 不是头节点
prev.next = current.next
} else { // 是头节点
hi.head = current.next
}
}
return true
} else {
// 当前批次数量不足,尝试合并后续批次
remainingNeed := required_quantity - current.quantity
if hi.mergeSubsequentBatches(current, herb_name, remainingNeed) {
return true
} else {
fmt.Printf("错误:库存不足,无法满足%d%s的需求\n", required_quantity, herb_name)
return false
}
}
}
prev = current
current = current.next
}
fmt.Printf("错误:库存中没有%s的批次\n", herb_name)
return false
}
// 辅助方法:合并后续同种药材批次
func (hi *HerbInventory) mergeSubsequentBatches(startNode *BatchNode, herb_name string, remainingNeed int) bool {
current := startNode.next
for current != nil && remainingNeed > 0 {
if current.herb_name == herb_name {
if current.quantity >= remainingNeed {
current.quantity -= remainingNeed
fmt.Printf("出库成功:从批次%s消耗%d%s\n", current.batch_id, remainingNeed, herb_name)
if current.quantity == 0 { // 该批次已耗尽
startNode.next = current.next
}
remainingNeed = 0
return true
} else {
remainingNeed -= current.quantity
startNode.next = current.next // 跳过已耗尽批次
current = startNode.next
}
} else {
current = current.next
}
}
return remainingNeed == 0
}
// 打印当前库存状态(按入库顺序)
func (hi *HerbInventory) printInventory() {
if hi.head == nil {
fmt.Println("库存为空")
return
}
fmt.Println("当前库存批次(按入库顺序):")
current := hi.head
for current != nil {
fmt.Printf("批次ID: %s, 药材: %s, 入库日期: %s, 剩余数量: %d\n",
current.batch_id, current.herb_name, current.inbound_date, current.quantity)
current = current.next
}
}
// 使用示例
func main() {
warehouse := &HerbInventory{}
// 入库操作(按时间顺序,批号优先测试,暂不考虑产地,规格及其他信息)
warehouse.addBatch("Lot-d2025001", "当归", "2025-01-15", 500)
warehouse.addBatch("Lot-h2025002", "黄芪", "2025-02-20", 250)
warehouse.addBatch("Lot-x2025003", "西洋参", "2025-03-10", 200)
warehouse.addBatch("Lot-r2025004", "人参", "2025-04-05", 100)
fmt.Println("\n🚀初始库存状态,单位:克")
warehouse.printInventory()
// 抓药操作
fmt.Println("\n--- 抓药操作1: 从当归批次消耗100克 ---")
warehouse.dispenseHerb("当归", 100) // 500-100
fmt.Println("--- 抓药操作2: 从当归批次消耗150克 ---")
warehouse.dispenseHerb("黄芪", 150) // 250-150
fmt.Println("--- 抓药操作3: 从黄芪批次消耗60克 ---")
warehouse.dispenseHerb("西洋参", 60) // 200-60
fmt.Println("--- 抓药操作4: 从人参批次消耗30克 ---")
warehouse.dispenseHerb("人参", 30) // 100-30
fmt.Println("\n🧭最终库存状态,单位:克")
warehouse.printInventory()
}
[Java-----------------------------------------------------------------------------------------------------]
// ==================== ERP单链模块 ====================
// 单向数据流 // 信息只能向前传递的内存通道 💾
// ⚠️ERP老兵_冷溪虎山:通道阻塞会引发数据洪灾
// 定义库存批次节点
class BatchNode {
String batch_id; // 批次ID
String herb_name; // 药材名称
String inbound_date; // 入库日期(字符串格式"YYYY-MM-DD")
int quantity; // 剩余数量
BatchNode next; // 下一个批次指针
// 构造函数
public BatchNode(String batch_id, String herb_name, String inbound_date, int quantity) {
this.batch_id = batch_id;
this.herb_name = herb_name;
this.inbound_date = inbound_date;
this.quantity = quantity;
this.next = null;
}
}
// 定义药材库存类
class HerbInventory {
BatchNode head; // 链表头节点(最早入库的批次)
// 构造函数
public HerbInventory() {
this.head = null;
}
// 新批次入库(添加到链表尾部)
public void addBatch(String batch_id, String herb_name, String inbound_date, int quantity) {
BatchNode newNode = new BatchNode(batch_id, herb_name, inbound_date, quantity);
if (head == null) { // 空链表情况
head = newNode;
return;
}
BatchNode current = head;
while (current.next != null) { // 遍历到最后一个节点
current = current.next;
}
current.next = newNode; // 新批次添加到尾部
}
// 药材出库(从最早批次开始消耗)
public boolean dispenseHerb(String herb_name, int required_quantity) {
if (head == null) {
System.out.println("错误:库存中没有" + herb_name + "的任何批次");
return false;
}
// 特殊情况:头节点就是目标药材且数量足够
if (head.herb_name.equals(herb_name) && head.quantity >= required_quantity) {
head.quantity -= required_quantity;
System.out.println("出库成功:从批次" + head.batch_id + "消耗" + required_quantity + herb_name);
if (head.quantity == 0) { // 该批次已耗尽
head = head.next;
}
return true;
}
// 一般情况:需要遍历链表
BatchNode prev = null;
BatchNode current = head;
while (current != null) {
if (current.herb_name.equals(herb_name)) {
if (current.quantity >= required_quantity) {
current.quantity -= required_quantity;
System.out.println("出库成功:从批次" + current.batch_id + "消耗" + required_quantity + herb_name);
if (current.quantity == 0) { // 该批次已耗尽
if (prev != null) { // 不是头节点
prev.next = current.next;
} else { // 是头节点
head = current.next;
}
}
return true;
} else {
// 当前批次数量不足,尝试合并后续批次
int remainingNeed = required_quantity - current.quantity;
if (mergeSubsequentBatches(current, herb_name, remainingNeed)) {
return true;
} else {
System.out.println("错误:库存不足,无法满足" + required_quantity + herb_name + "的需求");
return false;
}
}
}
prev = current;
current = current.next;
}
System.out.println("错误:库存中没有" + herb_name + "的批次");
return false;
}
// 辅助方法:合并后续同种药材批次
private boolean mergeSubsequentBatches(BatchNode startNode, String herb_name, int remainingNeed) {
BatchNode current = startNode.next;
while (current != null && remainingNeed > 0) {
if (current.herb_name.equals(herb_name)) {
if (current.quantity >= remainingNeed) {
current.quantity -= remainingNeed;
System.out.println("出库成功:从批次" + current.batch_id + "消耗" + remainingNeed + herb_name);
if (current.quantity == 0) { // 该批次已耗尽
startNode.next = current.next;
}
remainingNeed = 0;
return true;
} else {
remainingNeed -= current.quantity;
startNode.next = current.next; // 跳过已耗尽批次
current = startNode.next;
}
} else {
current = current.next;
}
}
return remainingNeed == 0;
}
// 打印当前库存状态(按入库顺序)
public void printInventory() {
if (head == null) {
System.out.println("库存为空");
return;
}
System.out.println("当前库存批次(按入库顺序):");
BatchNode current = head;
while (current != null) {
System.out.println("批次ID: " + current.batch_id + ", 药材: " + current.herb_name + ", " +
"入库日期: " + current.inbound_date + ", 剩余数量: " + current.quantity);
current = current.next;
}
}
}
// 使用示例
class main151 {
public static void main(String[] args) {
HerbInventory warehouse = new HerbInventory();
// 入库操作(按时间顺序,批号优先测试,暂不考虑产地,规格及其他信息)
warehouse.addBatch("Lot-d2025001", "当归", "2025-01-15", 500);
warehouse.addBatch("Lot-h2025002", "黄芪", "2025-02-20", 250);
warehouse.addBatch("Lot-x2025003", "西洋参", "2025-03-10", 200);
warehouse.addBatch("Lot-r2025004", "人参", "2025-04-05", 100);
System.out.println("\n🚀初始库存状态,单位:克");
warehouse.printInventory();
// 抓药操作
System.out.println("\n--- 抓药操作1: 从当归批次消耗100克 ---");
warehouse.dispenseHerb("当归", 100); // 500-100
System.out.println("--- 抓药操作2: 从当归批次消耗150克 ---");
warehouse.dispenseHerb("黄芪", 150); // 250-150
System.out.println("--- 抓药操作3: 从黄芪批次消耗60克 ---");
warehouse.dispenseHerb("西洋参", 60); // 200-60
System.out.println("--- 抓药操作4: 从人参批次消耗30克 ---");
warehouse.dispenseHerb("人参", 30); // 100-30
System.out.println("\n🧭最终库存状态,单位:克");
warehouse.printInventory();
}
}
[以上就是四语言截图和编码---------------------------------------✅✅✅✅✅✅]
🚨 怪蜀黎野路子宣言
**“别再看那些纸上谈兵的教程了!咱的代码:
- 能直接塞进药厂ERP系统跑生产环境
- 用了中医灵气流动比喻内存指针(头节点=百会穴,next指针=任脉传导)
- 开源4语言对照版,让你学一次掌握四种语法精髓”,学透单链表本质
💡 怪蜀黎提示:
- 直接复制代码跑通单链表基础操作
- 修改
dispenseHerb()方法适配你的业务逻辑(如快递仓储/服务器资源调度) - 中医黑话注释仅供娱乐,技术核心是FIFO链式管理!
👉 代码已就绪,剩下交给你的想象力!
(冷溪虎山数字本草实验室 © 2025 | 技术交流禁医疗用途)
🔮 下一步行动
- 立马白嫖 → GitHub仓库 Star后直接clone运行 (预告)
- 延伸学习 → 关注我的专栏《中医编程宇宙》系列(已爆11/14篇)
- 挑战升级 → 在评论区留下你想看的下个实战场景(如:用红黑树管理热门冷背药材)
💊 合规声明:
本代码完全模拟GMP规范设计,实际药厂应用需通过药监局验收。但代码里的审计追踪设计,能治你的“系统漏洞”和“数据淤堵”。
💊 免责声明:
本代码仅技术演示,实际用药请遵医嘱。但代码里的中医哲学,能治你的“知识虚火”和“学习淤堵”。
如有不对之处,欢迎评论区批评指出或者留言给我!✅✅
如果这份文章帮到了你,请点赞、收藏、关注三连!你们的支持,就是我继续‘炼丹’的动力🏆🏆!

浙公网安备 33010602011771号