C#多值列表搜索算法:基于UniqueID的邮件详情关联递归查询需求
解决方案:基于BFS的关联邮件遍历
这个需求本质是要遍历关联的邮件节点,手动一层层搜索确实繁琐,用**广度优先搜索(BFS)**搭配索引字典就能高效解决,既避免重复遍历列表,又能确保找到所有关联的邮件条目。
核心思路
- 构建快速索引:把两个邮件列表合并,为每个邮件的
UniqueID、MessageID、ReplyID建立索引字典,这样能在O(1)时间内找到对应ID的邮件,不用每次都遍历整个列表。 - BFS遍历关联节点:从初始
UniqueID对应的邮件开始,用队列逐步扩展搜索范围,每次取出队列中的邮件,再搜索它的MessageID和ReplyID对应的邮件,直到队列为空。同时用HashSet记录已访问的邮件,避免重复处理和循环引用。
完整代码实现
1. 构建索引工具方法
private Dictionary<string, List<EmailDetails>> BuildEmailIndex(List<EmailDetails> inbox, List<EmailDetails> sent) { var emailIndex = new Dictionary<string, List<EmailDetails>>(); // 合并收件箱和发件箱的所有邮件 var allEmails = inbox.Concat(sent).ToList(); foreach (var email in allEmails) { // 为UniqueID添加索引 AddEmailToIndex(emailIndex, email.UniqueID, email); // 为MessageID添加索引(排除空值) if (!string.IsNullOrEmpty(email.MessageID)) AddEmailToIndex(emailIndex, email.MessageID, email); // 为ReplyID添加索引(排除空值) if (!string.IsNullOrEmpty(email.ReplyID)) AddEmailToIndex(emailIndex, email.ReplyID, email); } return emailIndex; } private void AddEmailToIndex(Dictionary<string, List<EmailDetails>> index, string idKey, EmailDetails email) { if (!index.ContainsKey(idKey)) { index[idKey] = new List<EmailDetails>(); } index[idKey].Add(email); }
2. 关联邮件搜索方法
public List<EmailDetails> FindAllRelatedEmails(string initialUniqueId, List<EmailDetails> inboxEmails, List<EmailDetails> sentEmails) { var emailIndex = BuildEmailIndex(inboxEmails, sentEmails); var visitedEmails = new HashSet<EmailDetails>(); var searchQueue = new Queue<EmailDetails>(); var relatedEmails = new List<EmailDetails>(); // 先找到初始UniqueID对应的邮件,加入队列和结果集 if (emailIndex.TryGetValue(initialUniqueId, out var initialMatches)) { foreach (var email in initialMatches) { if (!visitedEmails.Contains(email)) { visitedEmails.Add(email); searchQueue.Enqueue(email); relatedEmails.Add(email); } } } // 开始BFS遍历所有关联邮件 while (searchQueue.Count > 0) { var currentEmail = searchQueue.Dequeue(); // 搜索当前邮件MessageID对应的关联邮件 if (!string.IsNullOrEmpty(currentEmail.MessageID) && emailIndex.TryGetValue(currentEmail.MessageID, out var messageIdMatches)) { foreach (var email in messageIdMatches) { if (!visitedEmails.Contains(email)) { visitedEmails.Add(email); searchQueue.Enqueue(email); relatedEmails.Add(email); } } } // 搜索当前邮件ReplyID对应的关联邮件 if (!string.IsNullOrEmpty(currentEmail.ReplyID) && emailIndex.TryGetValue(currentEmail.ReplyID, out var replyIdMatches)) { foreach (var email in replyIdMatches) { if (!visitedEmails.Contains(email)) { visitedEmails.Add(email); searchQueue.Enqueue(email); relatedEmails.Add(email); } } } } return relatedEmails; }
使用示例
比如你传入UniqueID = "2"时:
- 先找到
UniqueID为"2"的邮件,提取它的MessageID="b"和ReplyID="h"; - 搜索
MessageID="b"对应的邮件,将其加入队列和结果集; - 继续处理队列中的新邮件,提取它的
MessageID和ReplyID,重复搜索流程,直到没有新的关联邮件加入队列。
这个方案能高效处理任意规模的邮件列表,而且能完美应对循环关联的场景(比如A回复B,B又回复A的情况)。
内容的提问来源于stack exchange,提问作者Chamara Madusha
相关产品推荐
相关产品推荐

