攻克数据结构和算法——第四天:字典

简介: 字典有顺序存储,链式存储和散列表示三种存储方式,其中,链式存储又有跳跃链表和树形结构两种方式存储。

一,字典的基本概念


a4fc731534fd4a5087235844d008c7c5.png


操作:检索、插入元素和删除元素,其中最主要的运算是进行检索


●检索:给定一个key ,在字典中找出关键码等于key的元素


字典有顺序存储,链式存储和散列表示三种存储方式,其中,链式存储又有跳跃链表和树形结构两种方式存储。


静态字典: 一旦建立好,基本不动


动态字典:经常需要更新


评价标准:平均检索长度( Average Search Length )


68e05e8bb55e487b84f88ca197511f3b.png


二,跳跃链表


1,跳跃链表的基本概念


链表其缺点是只能顺序查找,即使是有序的链表也不能实现二分查找操作。跳跃链表(skiplist) 是有序链表的变种,它能够达到O(log n)的查找性能,是一种高效的字典结构。在单链表中只有一个指向直接后继的指针,而在跳跃链表中增加指向其他后继结点的指针,使得访问链表的过程中可以交替的跳过他的直接后继结点,


f6edc24b24e441a7a35a947590dbf034.png


横向叫做层,竖向叫做塔。


越高层链表结点是底层链表结点的子集,底层结点包含了所有词条,跳跃链表查找时从最高层开始找,最坏的情况就是找到最低层。


2,跳跃链表的建立和查找


#define MAX_ LEVEL 6    //定义最大层数
typedef int KeyType;    //跳跃链表结点结构定义
typedef struct node
{
    int level;    //结点层数
    KeyType key;    //结点的值
    struct node *next[MAX_ LEVEL]; // 指针数组
}*PNode;
//跳跃链表结构定义
typedef struct
{
    int num;     //跳跃链表数据个数
    int maxLevel;    //跳跃链表最大层数
    PNode head; // 跳跃链表的头指针
}*SkipList;


//创建带有头结点的空跳跃链表
SkipList SetNullSkipList(int level)
{
    SkipList list = (SkipList)malloc(sizeof(SkipList));
    if (list == NULL)//申请内存失败
        return NULL;
    list->num= 0; //空跳跃链表计数器赋值0
    list->maxLevel = level; //跳跃链表的层数
    list->head = CreateNode(level, -1://头结点的数据域赋值为-1
    if (list->head == NULL)
    {
        free(list); return NULL;
    }
    for (inti= 0;i< level; i++) //头结点的每一层的后继为空
        list- >head->next[i] = NUL;
    return list;
}


生成一个新结点


PNode CreateNode(int level, KeyType key) //生成个一新结点
{
    PNode p = (PNode)malloc(sizeof(struct node) + sizeof(PNode)*level);
    if (p == NULL) return NULL;
    p->level = level;
    p->key = key;
    return p;
}


查找:


PNode SkipListSearch(SkipList list, KeyType key) 
//按值查找,存在返回key的位置,失败返回NULL
{
    int n = 0;PNode p = NULL, q = NULL; p = list->head;
    for (int i-lit->maxLevel- 1;i>= 0; i) //从高层开始,纵向逐层比较
    {
        while ((q = p->next[i]) && (q->key <= key)) //横向比较
        {
            p= q;
            n++;    //记录比较次数
            if (p->key == key)
                { printf("%d\n", n); return p; }
        }
    }
    return NULL;
} 


查找算法过程:假设要查找元素key,从最高层的指针开始,如果找到该元素,则返回结点指针。如果到达了链表的末尾,或者找到大于key的某个元素elem,接着降低一层,从包含elem的那个结点的前一个结点重新开始查找。重复该过程直到找到key,或者在第一层查找达到了链表末尾,或者找到了一个大于key的元素。


3,跳跃链表的插入和删除:


插入过程:首先进行查找,查找成功,返回0 (因为在这里约定不能有相同的key)故不再插入。查找失败,则创建一个结点, 接着,逐层修改关联的指针,跳跃链表的计数器加1.


创建结点的层数根据投币产生,在算法中使用逻辑表达式rand() % 2来模拟投币过程,通过(伪)随机数的奇偶来模拟一次理想的投币过程。 根据RandomLevel的返回值插入到相应的层。


//插入结点,成功返回1,否则返回0
int SkipListInsert(SkipList list, KeyType key)
{
    int level = 0;
    PNode Pre[MAX_ LEVEL]; //记录每层的前驱结点位置
    PNode p, q = NULL;
    p = list->head;
    //查找位置,记录前驱结点信息
    for (int i= list->maxLevel- 1; i>= 0; i--) //纵向控制层
    {
        //横向查找插入位置,而for循环是 纵向移动查找位置
        while ((q = p->next[i]) && (q->key< key)) p= q;
        Pre[i]= p;
    }
    //已经存在相同的key,不能插入
    if ((q != NULL) && (q->key == key)) return 0;
    level = RandomLevel(list->maxLevel); /产生-一个随机层数
    p = CreateNode(level, key); //创建新结点
    if (p == NULL) return 0;
    //纵向逐层修改指针
    for (inti= 0;i< level; i++)
    {
        p->next[i] = Pre[i]->next[i];
        Pre[i]->next[i]= p;
    }
    list->num++; //跳跃链表的计数器加1
    return 1;
}


int RandomLevelint maxlevel)//产生随机层数,在各塔中自底向上逐层生长。
{
    int i= 1;
    while (rand() % 2)
        i++;
    i= (i> maxlevel) ? maxlevel :i;
    return i; 
}


三,散列表的概念


这个地方的内容我会放到数据结构里面讲,这里就不做讲解了。

目录
相关文章
|
7天前
|
搜索推荐 算法 Java
Java数据结构与算法:排序算法之插入排序
Java数据结构与算法:排序算法之插入排序
|
7天前
|
搜索推荐 算法 Java
Java数据结构与算法:排序算法之冒泡排序
Java数据结构与算法:排序算法之冒泡排序
|
7天前
|
搜索推荐 算法 Java
Java数据结构与算法:排序算法之归并排序
Java数据结构与算法:排序算法之归并排序
|
7天前
|
搜索推荐 算法 Java
Java数据结构与算法:排序算法之选择排序
Java数据结构与算法:排序算法之选择排序
|
6天前
|
存储 设计模式 算法
数据结构,算法宏观印象构建
数据结构,算法宏观印象构建
|
6天前
|
存储 算法 调度
算法与数据结构-栈篇
算法与数据结构-栈篇
12 0
|
7天前
|
人工智能 算法
程序技术好文:算法与数据结构
程序技术好文:算法与数据结构
|
5天前
|
算法 安全 数据库
基于结点电压法的配电网状态估计算法matlab仿真
**摘要** 该程序实现了基于结点电压法的配电网状态估计算法,旨在提升数据的准确性和可靠性。在MATLAB2022a中运行,显示了状态估计过程中的电压和相位估计值,以及误差随迭代变化的图表。算法通过迭代计算雅可比矩阵,结合基尔霍夫定律解决线性方程组,估算网络节点电压。状态估计过程中应用了高斯-牛顿或莱文贝格-马夸尔特法,处理量测数据并考虑约束条件,以提高估计精度。程序结果以图形形式展示电压幅值和角度估计的比较,以及估计误差的演变,体现了算法在处理配电网状态估计问题的有效性。
|
1天前
|
数据采集 存储 算法
基于BP算法的SAR成像matlab仿真
**摘要:** 基于BP算法的SAR成像研究,利用MATLAB2022a进行仿真。SAR系统借助相对运动合成大孔径,提供高分辨率图像。BP算法执行回波数据预处理、像素投影及图像重建,实现精确成像。优点是高精度和强适应性,缺点是计算量大、内存需求高。代码示例展示了回波生成、数据处理到插值显示的全过程。
|
9天前
|
机器学习/深度学习 自然语言处理 算法
m基于深度学习的OFDM+QPSK链路信道估计和均衡算法误码率matlab仿真,对比LS,MMSE及LMMSE传统算法
**摘要:** 升级版MATLAB仿真对比了深度学习与LS、MMSE、LMMSE的OFDM信道估计算法,新增自动样本生成、复杂度分析及抗频偏性能评估。深度学习在无线通信中,尤其在OFDM的信道估计问题上展现潜力,解决了传统方法的局限。程序涉及信道估计器设计,深度学习模型通过学习导频信息估计信道响应,适应频域变化。核心代码展示了信号处理流程,包括编码、调制、信道模拟、降噪、信道估计和解调。
31 8