当前位置: 首页 > article >正文

C#搜索算法大冒险:在数据海洋里找宝藏

在数据的广阔海洋里,搜索算法就像是一群神奇的寻宝猎人,帮助我们从海量的数据中找到想要的 “宝藏”。无论是查找一个数字、一条信息,还是一个特定的元素,搜索算法都能大显身手。今天,就让我们跟着几位 “寻宝高手”,开启这场刺激的搜索大冒险!

顺序搜索:勤劳的 “地毯式搜索员”

顺序搜索就像一位勤劳的工作人员,在一大片田野里寻找丢失的钥匙。他从田野的一端开始,一格一格地仔细查找,不放过任何一个角落。在数据的世界里,顺序搜索就是从数组的第一个元素开始,一个一个地比较,直到找到目标元素或者遍历完整个数组。

比如说,我们有一个数组 [3, 7, 1, 9, 4],现在要找数字 9。顺序搜索就会先看第一个数字 3,发现不是 9;再看第二个数字 7,也不是;接着看第三个数字 1,还是不是;看到第四个数字 9,终于找到了!

用 C# 代码实现顺序搜索如下:

using System;
class SequentialSearch

{

 public static int Search(int[] arr, int target)

 {

 for (int i = 0; i < arr.Length; i++)

 {

 if (arr[i] == target)

 {

 return i;

 }

 }

 return -1;

 }

}

调用这个方法:

class Program
{

 static void Main()

 {

 int[] numbers = { 3, 7, 1, 9, 4 };

 int target = 9;

 int result = SequentialSearch.Search(numbers, target);

 if (result!= -1)

 {

 Console.WriteLine($"找到了,目标元素在索引 {result} 处");

 }

 else

 {

 Console.WriteLine("没找到目标元素");

 }

 }

}

顺序搜索简单直接,就像一个老实巴交的人,做事一步一个脚印。但它的效率不高,尤其是数据量很大的时候,就像在大海里捞针,要花费很多时间。时间复杂度是 ,n 表示数据的数量。

二分搜索:聪明的 “折半查找者”

二分搜索是个聪明的家伙,就像猜数字游戏里那个总能快速猜对的高手。它只在有序数组里施展魔法,每次把搜索范围缩小一半。

假设我们有一个有序数组 [1, 3, 5, 7, 9, 11, 13],要找数字 7。二分搜索先看中间的数字,数组长度是 7,中间索引是 3,对应数字是 7,哇,一下子就找到了!如果要找的是数字 8,中间数字 7 比 8 小,那就把搜索范围缩小到 7 后面的部分 [9, 11, 13],再找这部分的中间数字,继续比较,直到找到或者确定数字不存在。

C# 实现二分搜索的代码:

using System;
class BinarySearch

{

 public static int Search(int[] arr, int target)

 {

 int left = 0;

 int right = arr.Length - 1;

 while (left <= right)

 {

 int mid = left + (right - left) / 2;

 if (arr[mid] == target)

 {

 return mid;

 }

 else if (arr[mid] < target)

 {

 left = mid + 1;

 }

 else

 {

 right = mid - 1;

 }

 }

 return -1;

 }

}

调用代码:

class Program
 {

 static void Main()

 {

 int[] numbers = { 1, 3, 5, 7, 9, 11, 13 };

 int target = 7;

 int result = BinarySearch.Search(numbers, target);

 if (result!= -1)

 {

 Console.WriteLine($"找到了,目标元素在索引 {result} 处");

 }

 else

 {

 Console.WriteLine("没找到目标元素");

 }

 }

}

二分搜索的效率很高,时间复杂度是 ,就像坐电梯上楼,每次都能跳过一半的楼层,很快就能到达目的地。不过,它的前提是数组必须有序,不然就没法施展它的魔法啦。

深度优先搜索(DFS):勇敢的 “迷宫探险家”

深度优先搜索就像一个勇敢的探险家,走进一个巨大的迷宫。他沿着一条路一直往前走,直到走到死胡同或者找到出口。如果是死胡同,就退回到上一个路口,换一条路继续探索。

在数据结构里,比如在树或者图中,DFS 从一个起始节点开始,沿着一条路径尽可能深地探索下去,直到无法继续或者达到目标节点,然后回溯,继续探索其他路径。

想象有一棵简单的树,根节点是 1,它有两个子节点 2 和 3,节点 2 又有子节点 4 和 5,节点 3 有子节点 6。如果从节点 1 开始进行 DFS 搜索节点 6,它会先沿着 1 - 2 - 4 这条路走,发现 4 不是目标节点,回溯到 2,再走 2 - 5 这条路,发现 5 也不是,回溯到 1,最后走 1 - 3 - 6 这条路,找到目标节点 6。

用 C# 实现一个简单的树的 DFS 遍历(这里用递归方式):

using System;
using System.Collections.Generic;

class TreeNode

{

 public int Value { get; set; }

 public List<TreeNode> Children { get; set; }

 public TreeNode(int value)

 {

 Value = value;

 Children = new List<TreeNode>();

 }

}

class DFS

{

 public static void Traverse(TreeNode node, int target)

 {

 if (node == null)

 {

 return;

 }

 Console.Write(node.Value + " ");

 if (node.Value == target)

 {

 Console.WriteLine("\n找到了目标节点");

 }

 foreach (TreeNode child in node.Children)

 {

 Traverse(child, target);

 }

 }

}

调用代码:

class Program
 {

 static void Main()

 {

 TreeNode root = new TreeNode(1);

 TreeNode node2 = new TreeNode(2);

 TreeNode node3 = new TreeNode(3);

 TreeNode node4 = new TreeNode(4);

 TreeNode node5 = new TreeNode(5);

 TreeNode node6 = new TreeNode(6);

 root.Children.Add(node2);

 root.Children.Add(node3);

 node2.Children.Add(node4);

 node2.Children.Add(node5);

 node3.Children.Add(node6);

 int target = 6;

 Console.WriteLine("DFS遍历:");

 DFS.Traverse(root, target);

 }

}

DFS 很适合探索那些有复杂分支结构的数据,它的时间复杂度取决于数据结构的规模,一般在树中是 ,在图中如果有 V 个顶点和 E 条边,时间复杂度是 。

广度优先搜索(BFS):细心的 “逐层探索者”

广度优先搜索是个细心的探索者,它在探索迷宫或者数据结构时,会一层一层地进行。就像在一个多层的大楼里找东西,它会从一楼开始,把一楼的每个房间都找遍,再去二楼,以此类推。

在树或图中,BFS 从起始节点开始,先访问它的所有邻居节点,再依次访问邻居节点的邻居节点,逐层扩展。

还是用刚才那棵树举例,从节点 1 开始 BFS 搜索节点 6。它先访问节点 1,然后访问 1 的邻居节点 2 和 3,接着访问 2 的邻居节点 4 和 5,再访问 3 的邻居节点 6,找到目标。

用 C# 实现树的 BFS 遍历(借助队列):

using System;
using System.Collections.Generic;

class TreeNode

{
 public int Value { get; set; }
 public List<TreeNode> Children { get; set; }
 public TreeNode(int value)
 {
 Value = value;
 Children = new List<TreeNode>();
 }
}

class BFS
{
 public static void Traverse(TreeNode root, int target)
 {
 if (root == null)
 {
 return;
 }
 Queue<TreeNode> queue = new Queue<TreeNode>();
 queue.Enqueue(root);
 while (queue.Count > 0)
 {
 TreeNode node = queue.Dequeue();
 Console.Write(node.Value + " ");
 if (node.Value == target)
 {
 Console.WriteLine("\n找到了目标节点");
 }
 foreach (TreeNode child in node.Children)
 {
 queue.Enqueue(child);
 }
 }
 }
}

调用代码:

class Program 
{ 
static void Main() 
{ 
TreeNode root = new TreeNode(1); 
TreeNode node2 = new TreeNode(2); 
TreeNode node3 = new TreeNode(3);
TreeNode node4 = new TreeNode(4); 
TreeNode node5 = new TreeNode(5); 
TreeNode node6 = new TreeNode(6); 
root.Children.Add(node2); 
root.Children.Add(node3); 
node2.Children.Add(node4); 
node2.Children.Add(node5); 
node3.Children.Add(node6); 
int target = 6; 
Console.WriteLine("BFS遍历:"); 
BFS.Traverse(root, target); 
} 
}

BFS 的时间复杂度和 DFS 类似,在树中是 ,在图中是 。它的优点是能找到从起始节点到目标节点的最短路径(如果路径长度定义为边的数量),就像在迷宫里总能找到最短路到达出口。

总结

顺序搜索老实可靠,但效率稍低;二分搜索聪明高效,不过有数据有序的前提;深度优先搜索勇敢无畏,适合探索复杂分支;广度优先搜索细心周到,能找最短路径。了解这些搜索算法的特点,在编程时就能像一个经验丰富的寻宝人,根据不同的 “宝藏” 和 “地形”,选择最合适的搜索算法,轻松找到想要的数据!下次遇到搜索问题,你知道该让哪位 “寻宝高手” 出马了吧?


http://www.kler.cn/a/546773.html

相关文章:

  • 【AI实践】deepseek支持升级git
  • Java发展史
  • 利用Firewalld和Iptables实现IP端口限制与开放
  • 牛客面筋学习
  • Flutter 双屏双引擎通信插件加入 GitCode:解锁双屏开发新潜能
  • Idea 插件 Quickly-Code-Toolkit
  • Oracle 19C Database Data Guard 一主两备 -- 生产级
  • springboot023学生宿舍管理系统
  • DNS污染、劫持频发?HTTPDNS让安全无死角
  • 在 Ubuntu 20.04 为 Clash Verge AppImage 创建桌面图标教程
  • macOS git status 中文现实不正常 -解决方法
  • Docker Desktop WebAPI《1》
  • 鸿蒙面试题
  • 【GeeRPC】Day6:负载均衡
  • Huatuo热更新--安装HybridCLR
  • Java 设计模式之备忘录模式
  • Oracle日常管理(8)——DB日常管理(1)
  • 网络性能测试工具ipref
  • Stable Diffusion 安装教程(附安装包) 【SD三种安装方式,Win+Mac一篇文章讲明白】
  • 深入浅出 Python Logging:从基础到进阶日志管理