算法-符号表的实现(顺序查找和二分查找)

符号表是一种存储键值对的数据结构,支持两种操作插入和查找,就是将一组新的键值对存入表中然后根据给定的键得到对应的值,在编程语言中常用Dictionary原理类似。符号表是一种典型的抽象数据结构,在生活之中应用的场景也很多,可以根据钥匙开门,域名解析的时候的IP地址查询,字典和图书的简介和页数,key和value是密不可分的,通过key我们可以很快找到我们需要的value。

无序链表的顺序查找

主要通过Node节点存储数据,之前的博客中有关于链表的实现,详情可参考之前的博客,代码有注释就解释太多了,代码如下:

@interface BaseNode : NSObject

@property  (strong,nonatomic)  NSString  *key;

@property  (strong,nonatomic)  NSString  *value;

@property  (strong,nonatomic)  BaseNode  *next;

-(void)setUpData:(NSString *)key  value:(NSString *)value  next:(BaseNode *)next;

@end

BaseNode.m的实现:

@implementation BaseNode

-(void)setUpData:(NSString *)key value:(NSString *)value next:(BaseNode *)next{
    self.key=key;
    self.value=value;
    self.next=next;
}

@end

顺序查找类中的代码:

@implementation SequenceTable

-(void)put:(NSString *)key value:(NSString *)value{
    //遍历节点
    for (BaseNode  *x=self.first; x!=NULL; x=x.next) {
        if ([x.key isEqualToString:key]) {
            x.value=value;return;
        }
    }
    //新的节点插在最前面,结构类似栈
    BaseNode  *tempNode=self.first;
    self.first=[[BaseNode alloc]init];
    [self.first setUpData:key value:value next:tempNode];
}

-(NSString *)get:(NSString *)key{
    //遍历数组存在返回值,否则返回null
    for (BaseNode  *node=self.first; node!=NULL; node=node.next) {
        if ([key isEqualToString:node.key]) {
            return  node.value;
        }
    }
    return NULL;
}

@end

 具体调用:

        SequenceTable  *table=[[SequenceTable alloc]init];
        [table put:@"FlyElephant" value:@"http://www.cnblogs.com/xiaofeixiang"];
        [table put:@"技术交流群" value:@"228407086"];
        NSLog(@"技术交流群:%@",[table get:@"技术交流群"]);

插入的时候先要查找,查找的时候需要从链表头进行查找,所以插入和查找的平均时间复杂度均为O(n),为了高效我们可以把符号表变成有序的进行二分查找。

有序数组的二分查找

将数组变成有序的我们进行二分查找能够将数组每次比较的次数大大减少,查找的时间复杂度变成O(lgN),插入的时间复杂度变成O(n),代码如下:

@interface BinarySearchTable : NSObject

@property (strong,nonatomic)  NSMutableArray  *keys;

@property  (strong,nonatomic) NSMutableArray  *values;

@property  (assign,nonatomic)  NSInteger  count;

-(void)put:(NSString *)key  value:(NSString *)value;

-(NSString *)get:(NSString *)key;

-(NSInteger)rank:(NSString *)key;

@end

实现代码如下:

@implementation BinarySearchTable

-(NSMutableArray *)keys{
    if (!_keys) {
        _keys=[[NSMutableArray alloc]initWithCapacity:1];
    }
    return _keys;
}

-(NSMutableArray *)values{
    if (!_values) {
        _values=[[NSMutableArray alloc]initWithCapacity:1];
    }
    return _values;
}
//添加新进入的键值对
-(void)put:(NSString *)key value:(NSString *)value{
    NSInteger index=[self rank:key];
    //如果存在键值对,更新值
    if (index<self.count&&[self.keys[index] isEqualToString:key]) {
        self.values[index]=value;return;
    }
    for (NSInteger  i=self.count; i>index; i--) {
        self.keys[i]=self.keys[i-1];
        self.values[i]=self.values[i-1];
    }
    self.keys[index]=key;
    self.values[index]=value;
    self.count=self.count+1;
}

-(NSString *)get:(NSString *)key{
    //查找键,如果存在则返回值,否则返回null
    NSInteger  index=[self rank:key];
    if (index<self.count&&[self.keys[index] isEqualToString:key]) {
        return self.values[index];
    }
    return NULL;
}

-(NSInteger)rank:(NSString *)key{
    //如果存在键则返回该键的位置,可以理解为表中小于它键的数量
    NSInteger  low=0,high=self.count-1;
    while (low<=high) {
        NSInteger  mid=low+(high-low)/2;
        NSInteger  diff=[key integerValue]-[self.keys[mid] integerValue];
        if (diff>0) {
            low=mid+1;
        }
        else if (diff<0){
            high=mid-1;
        }else{
            return mid;
        }
    }
    return low;
}

@end

测试代码:

       SequenceTable  *table=[[SequenceTable alloc]init];
        [table put:@"FlyElephant" value:@"http://www.cnblogs.com/xiaofeixiang"];
        [table put:@"技术交流群" value:@"228407086"];
        NSLog(@"技术交流群:%@",[table get:@"技术交流群"]);

        BinarySearchTable  *binaryTable=[[BinarySearchTable alloc]init];
        [binaryTable put:@"3" value:@"FlyElephant"];
        [binaryTable put:@"9" value:@"keso"];
        [binaryTable put:@"10" value:@"博客园"];
        [binaryTable put:@"0" value:@"228407086"];
        NSString  *temp=[binaryTable get:@"3"];
        NSLog(@"博客园:%@",temp);

效果:

时间: 2024-10-11 18:10:39

算法-符号表的实现(顺序查找和二分查找)的相关文章

2. C#数据结构与算法 -- 查找算法(顺序查找,哈希查找,二分查找(折半),索引,二叉)

1. 顺序查找算法 ===================================================== 算法思想简单描述: 最突出的查找类型就是从记录集的开始处顺次遍历每条记录,直到找到所要的记录或者是 到达数据集的末尾.这就是所谓的顺序查找.顺序查找(也被称为线性查找)是非常容易实现 的.从数组的起始处开始,把每个访问到的数组元素依次和所要查找的数值进行比较.如果找 到匹配的数据项,就结束查找操作.如果遍历到数组的末尾仍没有产生匹配,那么就说明此数 值不在数组内. ==

Java中常用的查找算法——顺序查找和二分查找

Java中常用的查找算法——顺序查找和二分查找 一.顺序查找: a) 原理:顺序查找就是按顺序从头到尾依次往下查找,找到数据,则提前结束查找,找不到便一直查找下去,直到数据最后一位. b) 图例说明: 原始数据:int[] a={4,6,2,8,1,9,0,3}; 要查找数字:8 代码演示: import java.util.Scanner; /* * 顺序查找 */ public class SequelSearch { public static void main(String[] arg

【Java_Base】常用查找算法:顺序查找、二分查找

顺序查找 从第一个元素开始顺序比较查找. 二分查找 二分查找前提条件: 已排序的数组中查找 二分查找的基本思想是: 首先确定该查找区间的中间点位置: int mid = (low+upper) / 2; 然后将待查找的值与中间点位置的值比较: 若相等,则查找成功并返回此位置. 若中间点位置值大于待查值,则新的查找区间是中间点位置的左边区域. 若中间点位置值小于待查值,则新的查找区间是中间点位置的右边区域. 下一次查找是针对新的查找区间进行的. 1 public class Search{ 2 p

算法-基础和查找-1.汉诺塔/2.顺序查找/3.二分查找/4.顺序查找和二分查找的比较

1.汉诺塔: 如下图所示,需要将A柱子中的所有圆盘按照从小到大的顺序移动到C柱子上,并且在移动过程中大圆盘不能在小圆盘上面 分析问题:最终希望呈现的结果是将A柱子上的盘子全部按照从小到大的顺序移动到C柱子上 1.n个盘子,将n-1视为一个整体 2.将n-1个盘子视为一个盘子从a经过c移动到b 3.将n从a移动到c 4.将n-1个盘子从b经过a移动到c 5.结束条件:n>0 代码如下: 1 def hanoi(n, a, b, c): 2 if n > 0: 3 hanoi(n-1, a, c,

顺序查找和二分查找

1.使用PHP描述顺序查找和二分查找(也叫做折半查找)算法,顺序查找必须考虑效率,对象可以是一个有序数组[转] 2.顺序查找 <?php//$n为待查找的数组元素的个数,$k为待查找的元素function seq_sch($array, $n, $k){ $array[$n] = $k; for($i=0; $i<$n; $i++){ if($array[$i]==$k){ return true;break; } } if ($i<$n) //判断是否到数组的末尾{ return $i

查找系列之简述顺序查找和二分查找

顺序查找和二分查找 一.顺序查找思想 1. 从表的一端开始扫描,顺序扫描线性表,依次扫描到的结点关键字与给定的值K相比较.如果当前扫描到的结点的关键字与给定的值K相等,则查找成功;若扫描结束后,仍未找到关键字与给定的值K相等,则查找失败; 2.顺序查找既适用于顺序存储结构,也适用于线性表的链式存储结构; 3.ASL= (n+1)/2为其平均查找长度 4.优点:算法简单,对存储结构形式没有要求 缺点:浪费空间,当长度非常大是效率低 5.算法描述: /** *顺序查找 *@param int a[]

看数据结构写代码(53) 静态查找表(线性查找,二分查找,斐波那契查找,插值查找)

查找定义:根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录). 查找表分类:静态查找表和动态查找表. 静态查找表:只查找,而不进行插入,删除. 动态查找表:在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素. 静态表的 查找 大致 四种 算法: 线性查找,二分查找,斐波那契查找和插值查找. 其中 在线性查找之前,对表 无要求.对于 其余三种 需要 在查找之前 排序.插值查找 除了 需要 排序,还需要 均匀分布. 下面 给出代码: 线性查

动态数组,数组初始化,数组内存释放,向数组中添加一个元素,向数组中添加多个元素,数组打印,顺序查找,二分查找,查找数组并返回地址,冒泡排序,改变数组中某个元素的值,删除一个数值,删除所有,查找含有

 1定义接口: Num.h #ifndef_NUM_H_ #define_NUM_H_ #include<stdio.h> #include<stdlib.h> /************************************************************************/ /*数组的结构体类型                                                    */ /*******************

对分查找法(二分查找法,折半查找法)

二分查找法是针对已经排好序的序列进行查找 每次折半查找 算法时间复杂度,对于长度为N的序列,每次执行N/2,假设k次结束,最后到第一个N/2^k=0,所以k=logN 时间复杂度logN int binarysearch(const int array[], int x, int N) { int low, mid, high; low = 0, high = N - 1; while (low <= high) { mid = (low + high) / 2; if(array[mid] <