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

一个网站占空间有多少g个人网站 icp 代理

一个网站占空间有多少g,个人网站 icp 代理,潮安区住房和城乡建设局网站,门户网站自查报告Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》 欢迎点赞&#xff0c;关注&am…

         Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路!

我的博客:<但凡.

我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C++修炼之路》

欢迎点赞,关注!

目录

1、跳表引入

        1.1、背景

        1.2、跳表的基本原理

2、跳表模拟实现

        2.1、跳表节点

        2.2、跳表框架

        2.3、 查询

        2.4、 查找前置节点

        2.5、添加节点

        2.6、删除节点

3、跳表的性能分析


1、跳表引入

        1.1、背景

        跳表(Skip List)由美国计算机科学家威廉·普(William Pugh)于1989年提出,目的是解决有序链表查询效率低的问题。传统链表查询时间复杂度为O(n),而跳表通过引入多层索引结构,将查询、插入和删除操作的时间复杂度优化至O(log n),同时保持了较高的空间效率。普的论文《Skip Lists: A Probabilistic Alternative to Balanced Trees》奠定了跳表在数据结构领域的地位,成为平衡树轻量级替代方案


        1.2、跳表的基本原理

        跳表的核心思想是通过概率性构建多层索引加速查找。每一层都是有序链表,底层包含所有元素,上层逐步稀疏。稀疏与稠密是通过设置概率不同有所差别。每一个跳表的分布都是随机生成的。查找时从最高层开始,若当前节点的下一个节点值小于目标值,则向右移动;否则向下移动到下一层继续搜索。插入和删除操作通过调整相邻节点的指针实现,并动态维护索引层数。


2、跳表模拟实现

        2.1、跳表节点

        _val存储每个节点存储的值,_nextV指向下一个节点。

struct SkiplistNode
{int _val;vector<SkiplistNode*> _nextV;SkiplistNode(int val, int level):_val(val), _nextV(level, nullptr){}
};

        2.2、跳表框架

        对于跳表类的私有成员变量,有三个,_head是跳表的头,这个节点不存储值。_maxlevel存储最高层高,_p是晋升概率,也就是层高加一的概率。后面会详细说。

class Skiplist
{typedef SkiplistNode Node;
public:Skiplist(){srand(time(0));_head = new Node(-1, 1);}private:Node* _head;size_t _maxLevel = 32;double _p = 0.5;
};

        2.3、 查询

        我们先来说查找,一会在介绍怎么添加节点、

        对于查找的过程来说,我们从头结点开始查找,如果下一个节点的值小于我们想要查找的target,我们就直接跳到下一个节点那。如果下一个节点的值大于我们想要查找的taget,我们就得下降层数。如果层数下降到-1(0层是最低层)也没有找到target值,就跳出循环返回false。

        我们拿一个跳表模拟一下查找的过程:

bool search(int target)
{Node* cur = _head;int level = _head->_nextV.size() - 1;while (level >= 0){if (cur->_nextV[level] && cur->_nextV[level]->_val < target){cur = cur->_nextV[level];}//        走到最后一个节点else if (cur->_nextV[level] == nullptr || cur->_nextV[level]->_val > target){--level;}else{return true;}}return false;
}

        2.4、 查找前置节点

        首先我们先新建一个前置节点,然后把他初始化为level层,其实就是让他的层数和跳表中最高节点的层数相等。我们把这个前置节点的存储的值都初始化为_head。因为如果我们要查找的某个值都比跳表中的所有值都小,那么他的前置节点就是head。

        在循环的过程中,每次调整level我们就记录一下前置节点:

        后序删除和添加节点的时候我们都得先找到前置节点。

vector<Node*> FindPrevNode(int num)
{Node* cur = _head;int level = _head->_nextV.size() - 1;vector<Node*> prevV(level + 1, _head);while (level >= 0){if (cur->_nextV[level] && cur->_nextV[level]->_val < num){cur = cur->_nextV[level];}else if (cur->_nextV[level] == nullptr || cur->_nextV[level]->_val >= num){prevV[level] = cur;--level;}}return prevV;
}

        2.5、添加节点

         再添加节点的操作中,因为我们要控制每个跳表节点的高度都是随机的,所以说我们得先说一下生成随机层高的函数:

        随机数生成部分:

  generator是静态的默认随机数引擎

       用当前系统时间作为种子(time_since_epoch().count()),确保每次程序运行时种子不同static关键字保证在整个程序运行期间只初始化一次

   distribution:静态的均匀实数分布,范围[0.0, 1.0)用于生成0到1之间的随机浮点数。

        p是晋升概率,也就是我们层数++的概率。

        节点层数至少为1。而大于1的节点层数,满足一个概率分布。

        节点层数恰好等于1的概率为1-p。

        节点层数大于等于2的概率为p,而节点层数恰好等于2的概率为p(1-p)。

        节点层数大于等于3的概率为p^2,而节点层数恰好等于3的概率为p^2*(1-p)。

        节点层数大于等于4的概率为p^3,而节点层数恰好等于4的概率为p^3*(1-p)。

int RandomLevel()
{static std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count());static std::uniform_real_distribution<double> distribution(0.0, 1.0);size_t level = 1;while (distribution(generator) <= _p && level < _maxLevel){++level;}return level;
}

        接下来我们看添加节点操作。首先我们找到应该插入位置的前置节点,然后依次设置每一层的节点链接。

void add(int num)
{vector<Node*> prevV = FindPrevNode(num);int n = RandomLevel();Node* newnode = new Node(num, n);if (n > _head->_nextV.size()){_head->_nextV.resize(n, nullptr);prevV.resize(n, _head);}for (size_t i = 0;i < n;i++){newnode->_nextV[i] = prevV[i]->_nextV[i];prevV[i]->_nextV[i] = newnode;}
}

        2.6、删除节点

        最后需要注意我们得调整一下头结点的层数。

bool erase(int num)
{vector<Node*> prevV = FindPrevNode(num);if (prevV[0]->_nextV[0] == nullptr || prevV[0]->_nextV[0]->_val != num){//该节点不存在return false;}else{Node* del = prevV[0]->_nextV[0];for (size_t i = 0;i < del->_nextV.size();i++){prevV[i]->_nextV[i] = del->_nextV[i];}delete del;//如果删除了最高层节点,就把头结点层数降一下int i = _head->_nextV.size() - 1;while (i >= 0){if (_head->_nextV[i] == nullptr)--i;elsebreak;}_head->_nextV.resize(i+1);return true;}
}

 

3、跳表的性能分析

        时间复杂度查询、插入、删除均为O(log n),依赖随机层数分布。

        空间复杂度平均O(n),索引节点数量约为n/2 + n/4 +... ≈ n。

        时间复杂度都是由查询操作卡着,而查询操作其实是从上到下遍历一遍。跳表的高度通常为O(log n),其中n是节点数量。

        优势实现简单,无需复杂平衡操作;适合高并发场景(如Redis的有序集合)。

        跳表作为一种高效动态数据结构,兼具实用性与灵活性,是算法设计中的经典案例。

        好了,今天的内容就分享到这,我们下期再见! 

 


文章转载自:

http://fkd0OqQV.wfysn.cn
http://26dlkiq8.wfysn.cn
http://HpGKEYBE.wfysn.cn
http://bZ0Q51B6.wfysn.cn
http://P2NjItdd.wfysn.cn
http://bLqYXcEP.wfysn.cn
http://AbRlaO8s.wfysn.cn
http://9GhNcJOx.wfysn.cn
http://uTCE23mM.wfysn.cn
http://tekIecm1.wfysn.cn
http://GbvJ6V2G.wfysn.cn
http://MRO8SHYR.wfysn.cn
http://tY4qwlrX.wfysn.cn
http://yhQCwQu9.wfysn.cn
http://byuSS8ck.wfysn.cn
http://B0ji41Zc.wfysn.cn
http://eVsnX1sz.wfysn.cn
http://o4uo5bZj.wfysn.cn
http://7OTHfLKJ.wfysn.cn
http://YzoOLOMD.wfysn.cn
http://Oz8pnYRc.wfysn.cn
http://s78ffMbs.wfysn.cn
http://Ok9jf3D9.wfysn.cn
http://8VXQW8ZC.wfysn.cn
http://pt7WLlYz.wfysn.cn
http://IaXkqpbQ.wfysn.cn
http://qz59CujX.wfysn.cn
http://QkPxh68A.wfysn.cn
http://NVm16AAY.wfysn.cn
http://mp7qZ8Et.wfysn.cn
http://www.dtcms.com/wzjs/663215.html

相关文章:

  • 管理手机网站模板网站飘窗 两学一做
  • 设计师配色网站网站建设的销售好做吗
  • 个人网站建设方案书 学生孝感织云网站建设
  • wordpress建站怎么上传网站建站免费
  • 创世网站百度网站下载安装
  • 河南平台网站建设制作市场营销策划公司排名
  • 手机门户网站开发用iis建立网站
  • 北京市朝阳区网站制作公司网站开发找哪个
  • 在线制作书封网站如何认识软件开发模型
  • 企业建立网站的好处株洲网站建设网站建设
  • 网站建设服务方案ppt模板体育用品网站模板
  • ftp网站 免费湖南省交通建设质安监督局网站
  • 做网站威海给网站定位
  • 西安知名网站制作公司2022最新装修效果图
  • 房管局网站建设做网站需要用什么开发软件
  • 集约化网站建设的函西安营销型网站制作价格
  • 宁波网站建设rswl福州seo技巧培训
  • 模板做图 网站东莞做阀门的网站
  • 网站建设保密协议响水做网站的价格
  • 菏泽百度网站建设wordpress 相关文章 插件
  • wordpress网站数据迁移网上购物哪个商城好
  • 制作网站推广网络广告的形式有哪些?
  • 台州网站建设系统电子商务网站特色
  • 网站建设制作设计开发网页设计师就业形势
  • 查询网站所有关键词排名怎么劝客户做网站
  • 江西建设厅网站官网海外公司推广
  • 热门网站太仓做网站
  • 九江便宜做网站个人网站建设联系
  • 建站行业如何快速成第一单官方静态网站模板下载
  • 池州网站建设价格湖南长沙网站建