用顺序查找方法对stu.txt文件中的数据进行查找。_每天5分钟用C#学习数据结构(30)查找 Part 1...

d6f07c012938d36630deb4809dd69cba.png 【基础知识作者 / Edison Zhou 这是 恰童鞋骚年 的第 231 篇原创文章
只要你打开电脑,就会涉及到查找技术。如炒股软件中查股票信息、硬盘文件中找照片、在光盘中搜DVD,甚至玩游戏时在内存中查找攻击力、魅力值等数据修改用来作弊等,都要涉及到查找。当然,在互联网上查找信息就更加是家常便饭。查找是计算机应用中最常用的操作之 一,也是许多程序中最耗时的一部分,查找方法的优劣对于系统的运行效率影响极大。因此,本篇开始讨论一些查找方法。 1顺序查找

顺序查找(Sequential Search)又叫线性查找,是最基本的查找技术,它的查找过程是:从表中第一个(或最后一个)记录开始,逐个进行记录的关键字和给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录;如果直到最后一个(或第一个)记录,其关键字和给定值比较都不等时,则表中没有所查的记录,查找不成功。

顺序查找所用时间与查找关键字Key在线性表中的位置有关,其时间复杂度为O(n)。顺序查找的优点在于:算法简单易行,且对表的结构无任何要求(无论是顺序表还是链表,也无论是按关键字有序还是无序存放)。当然,其缺点也比较明显:算法效率较低,在较大规模的数据集合中进行查找时,不宜采用顺序查找

顺序查找的代码实现如下:

static void SequenceSearchDemo(){    int[] seqList = { 2, 8, 10, 13, 21, 36, 51, 57, 62, 69 };    Console.WriteLine("-------------基本顺序查找-------------");    Console.WriteLine("查找51:{0}", SequenceSearch(seqList, 51));    Console.WriteLine("查找8:{0}", SequenceSearch(seqList, 8));    Console.WriteLine("查找15:{0}", SequenceSearch(seqList, 15));}static int SequenceSearch(int[] seqList, int key){    int index = -1;    for (int i = 0; i < seqList.Length; i++)    {        if (seqList[i] == key)        {            index = i;            break;        }    }    return index;}

运行结果如下图所示:

2aee979b85ef435f311e4c4fcfa3e809.png

2二分查找

折半查找(Binary Search)技术,又称为二分查找。它的前提是线性表中的记录必须是关键码有序(通常从小到大有序),线性表必须采用顺序存储,其时间复杂度为O(logn)。

dc4ead3bdf168b19e2e733038071116f.png 折半查找的 基本思想 是: 在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相 等,则查找成功; 若给定值小于中间记录的关键字,则在中间记录的左半区继续查找; 若给定值大于中间记录的关键字,则在中间记录的右半区继续查找。 不断重复上述过程,直到查找成功,或所有查找区域无记录,查找失败为止。 折半查找的代码实现如下:
static void SeqSearchDemo(){    int[] seqList = { 2, 8, 10, 13, 21, 36, 51, 57, 62, 69 };    Console.WriteLine("-------------基本二分查找-------------");    Console.WriteLine("查找51:{0}", SeqSearch(seqList, 51));    Console.WriteLine("查找8:{0}", SeqSearch(seqList, 8));    Console.WriteLine("查找15:{0}", SeqSearch(seqList, 15));}static int SeqSearch(int[] seqList, int key){    int low = 0;    int high = seqList.Length - 1;    int mid;    while (low <= high)    {        mid = (low + high) / 2;        if (seqList[mid] == key)        {            return mid;        }        else if (seqList[mid] < key)        {            low = mid + 1;        }        else        {            high = mid - 1;        }    }    return -1;}
运行结果如下图所示: 0682679ef6f4261e5eb4ec7bc1736835.png Array.BinarySearch方法

38fa87bdadf0df52dfb1dd8cbb872657.png

在.NET中的数组类Array中,内置了一个二分查找的方法—Array.BinarySearch,它是一个静态方法。需要注意的是:在调用这个方法前,需要确保作为参数的查找表内的关键字已经有序,否则就需要手动调用Array.Sort()方法进行排序。

int[] seqList = { 32, 25, 8, 10, 13, 21, 36, 51, 57, 62, 69 };Console.WriteLine("-------------Array.BinarySearch-------------");Array.Sort(seqList);Console.WriteLine("查找51:{0}", Array.BinarySearch(seqList, 51));Console.WriteLine("查找69:{0}", Array.BinarySearch(seqList, 69));Console.WriteLine("查找15:{0}", Array.BinarySearch(seqList, 15));

在Array.BinarySearch()方法内部的求mid值的公式为:mid=low+((high-low)>>1),这是因为整数右移一位相当于整数除2操作,但位移运算的速度快于除法运算

c39e8c887806d67989ba6729c8b3f4de.png

System.Collections.SortedList类

1e21bcb2cd5a9b31f7a4fd3584722d61.png

在.NET中的System.Collections命名空间下,SortedList和SortedList两个类是用于存放键值对的集合类,它们的元素存储于线性表中,并按键值进行排序。其中SortedList使用了两个数组来分别存放key和value,并巧妙地运用了二分查找使得它的各项性能与ArrayList十分近似。

SortedList<string, string> studentList = new SortedList<string, string>();studentList.Add("005", "张三");studentList.Add("004", "李四");studentList.Add("006", "王五");studentList.Add("012", "马六");studentList.Add("002", "钱七");studentList.Add("009", "刘八");foreach (var item in studentList){    Console.WriteLine("{0}:{1}", item.Key, item.Value);}
运行结果为:

4584ea0748e31c7c7a46cb832d459e18.png

回过头来,我们看看SortedList类的Add方法,从中可以发现,它借助了Array.BinarySearch方法获取存储位置,也就是说它也使用了二分查找方法。

ccfb48bea2c05ade63191b007a62fd44.png

3小结

本篇介绍了查找算法中最基础的两个算法:顺序查找和二分查找,然后介绍了.NET BCL中提供的Array.BinarySearch方法以及SortedList类,他们都自带了二分查找的算法实现。

4参考资料 程杰,《大话数据结构》 陈广,《数据结构(C#语言描述)》 段恩泽,《数据结构(C#语言版)》 往期 精彩 回顾

每天5分钟用C#学习数据结构(29)

537ef452ed01b004ee2bd3a2c6adbca7.png 如果本文对你有用, 不妨点个“在看”或者转发朋友圈

0ea2ee7e8ed96ad8d7ac292e7861d865.png

?点击

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值