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

邵阳 做网站公司东西湖网站建设公司

邵阳 做网站公司,东西湖网站建设公司,西安企业网站建设公司,云游戏免费平台文章目录 1.跳表的基本概念2.跳表的结构3.跳表的增删改查4.完整代码 1.跳表的基本概念 跳表的本质是一种查找结构,一般查找问题的解法分为两个大类:一个是基于各种平衡树,一个是基于哈希表,跳表比较的特殊,它独成一派…

文章目录

        • 1.跳表的基本概念
        • 2.跳表的结构
        • 3.跳表的增删改查
        • 4.完整代码

1.跳表的基本概念

跳表的本质是一种查找结构,一般查找问题的解法分为两个大类:一个是基于各种平衡树,一个是基于哈希表,跳表比较的特殊,它独成一派。跳表是基于有序链表的基础上发展而来的,普通链表查找只能一个一个往下跳,而跳表能一次跳过好几个结点,这就是它查找效率高的原因。 例如:
如果只有一层那么查找就是逐个遍历,效率就是O(n)
在这里插入图片描述

如果为两个相邻结点添加第二层指向
在这里插入图片描述
甚至是添加第三层的指向
在这里插入图片描述
每层的结点个数呈现2:1的对应关系,查找就是从最高层开始,依次往下查找,这个过程类型二分查找,效率可以来到O(log n)。但是如果严格维持这种2:1的对应关系,插入删除节点都需要重新调整,插入删除效率直接就降到O(n)。所以跳表采用随机化结点的层数,来控制查找插入删除的时间复杂度近似为O(log n)。怎么计算可以参考博客。

2.跳表的结构

跳表的结点有多层,通过vector<SkiplistNode*> 来存储下一个结点的指针。初始化跳表时是带头结点的,它的层数要求是最高的,它开始只有它自己,默认给一层,后面插入的时候如果有结点的层数高于它,需要调整。

struct SkiplistNode
{	int _data;vector<SkiplistNode*> _nextV;SkiplistNode(int data,int level):_data(data),_nextV(level,nullptr){}
};class Skiplist
{typedef SkiplistNode Node;
private:Node* _head;int _maxLevel = 32;double _p = 0.25;public:Skiplist(){_head = new Node(-1,1);}
};int main()
{Skiplist list;	return 0;
}
3.跳表的增删改查

看看自己的代码有没有问题可以在leetcode上提交代码:题目链接
1)跳表的查找: 跳表中的元素是有序的,在理解跳表查找前先来看一下一个有序的单链表是如何查找元素的。
在这里插入图片描述
查找有序单链表,cur表示当前结点,如果cur的值data等于待查找的值target说明找到了。可如果cur 的下一个结点的值data大于target,说明target目标值不在链表中,或者是链表遍历到结尾还是找不到也说明target目标值不在链表中,这就是有序单链表的查找过程。
有了有序单链表的查找的基础,来看跳表的查找就简单了。
在这里插入图片描述
1、cur表示当前结点、next表示下一个结点、data表示结点的数据。
2、要从最高层找起,直到遍历到最低的那一层。
3、如果target 等于 cur的 data说明找到了。
4、如果target 大于 next 的 data,向右找。但是要保证next 不能为NULL。如找19而当前cur 的data是7,它的next 是NULL。不代表找不到,而是要到下一层找。
5、如果next的date 大于target 说明target可能在cur 和 next之间,往下一层找。

bool search(int target)
{Node* cur = _head;int level = cur->_nextV.size() -1;while(level >= 0){if(cur->_nextV[level] && cur->_nextV[level]->_data < target){cur = cur->_nextV[level];}else if(cur->_nextV[level] == nullptr || cur->_nextV[level]->_data > target){level--;}else {return true;}}return false;
}

2)跳表的插入: 类比单链表的从中间的某个位置插入。需要找到前一个位置prev。跳表要找的是prevV,前结点指针列表。
在这里插入图片描述
1、找到prevV
2、创建一个结点newNode,先让newNode->_nextV[i] 逐个指向 prevV[i]->_nextV[i]指向的结点。再让prevV[i]->_nextV[i]指向newNode。
3、这里创建newNode层数是随机的,需要根据概率计算。这里参照radis中给定的概率和最大层数。
4、如果插入节点的层数高于头结点,需要调整头结点的层数。

vector<Node*> findPervV(int num)
{Node* cur = _head;int level = _head->_nextV.size() -1;vector<Node*> prevV(level + 1,nullptr);while(level >= 0){			if(cur->_nextV[level] != nullptr && cur->_nextV[level]->_data < num){cur = cur->_nextV[level];}else if(cur->_nextV[level] == nullptr || cur->_nextV[level]->_data >= num){prevV[level] = cur;level--;}}return prevV;	
}void add(int num)
{int n = randomLevel();int level = _head->_nextV.size() -1;vector<Node*> prevV = findPervV(num);// 调整头结点的层数if(n > _head->_nextV.size()){_head->_nextV.resize(n,nullptr);prevV.resize(n,_head);}Node* newNode = new Node(num,n);	for(int i = 0;i < n;i++){			newNode->_nextV[i] = prevV[i]->_nextV[i];prevV[i]->_nextV[i] = newNode;}
}int randomLevel()
{Node* cur = _head;srand(time(NULL));int level= 1;// rand的区间范围为[0,RAND_MAX]while(rand() <= RAND_MAX*_p && level < _maxLevel) { level++;}return level;
}

3)跳表的删除:
1、要到前结点列表prevV
2、根据当前结点的层数,循环指向prevV[i]->_nextV[i] = del->_nextV[i]

bool erase(int num)
{vector<Node*> prevV = findPervV(num);if(prevV[0]->_nextV[0] == nullptr || prevV[0]->_nextV[0]->_data != num){return false;}else{Node* del = prevV[0]->_nextV[0];// 当前节点的层数for(int i = 0;i < del->_nextV.size();i++){prevV[i]->_nextV[i] = del->_nextV[i];}delete del;int index = _head->_nextV.size() -1;// _head->_nextV[index] == nullptr说明最高结点删除了,调整头结点while (index >= 0) {if(_head->_nextV[index] == nullptr) {index--;}else {break;}	}return true;}
}

4)跳表的打印: 这里按照单链表的思路打印,如果只看第一层那么跳表就像是有序的单链表。注意跳表是带头指针的,所以直接从_head->nextV[0]开始。

void print()
{Node* cur = _head->_nextV[0];while(cur != nullptr){			cout << cur->_data << "->";	cur = cur->_nextV[0];}cout << "NULL" << endl;
}
4.完整代码
#include <vector>
#include <iostream>
#include <time.h>
#include <stdlib.h>using namespace std;struct SkiplistNode
{	int _data;vector<SkiplistNode*> _nextV;SkiplistNode(int data,int level):_data(data),_nextV(level,nullptr){}
};class Skiplist
{typedef SkiplistNode Node;
private:Node* _head;int _maxLevel = 32;double _p = 0.25;public:Skiplist(){_head = new Node(-1,1);}bool search(int target){Node* cur = _head;int level = cur->_nextV.size() -1;while(level >= 0){if(cur->_nextV[level] && cur->_nextV[level]->_data < target){cur = cur->_nextV[level];}else if(cur->_nextV[level] == nullptr || cur->_nextV[level]->_data > target){level--;}else {return true;}}return false;}vector<Node*> findPervV(int num){Node* cur = _head;int level = _head->_nextV.size() -1;vector<Node*> prevV(level + 1,nullptr);while(level >= 0){			if(cur->_nextV[level] != nullptr && cur->_nextV[level]->_data < num){cur = cur->_nextV[level];}else if(cur->_nextV[level] == nullptr || cur->_nextV[level]->_data >= num){prevV[level] = cur;level--;}}return prevV;	}void add(int num){int n = randomLevel();int level = _head->_nextV.size() -1;vector<Node*> prevV = findPervV(num);if(n > _head->_nextV.size()){_head->_nextV.resize(n,nullptr);prevV.resize(n,_head);}Node* newNode = new Node(num,n);	for(int i = 0;i < n;i++){			newNode->_nextV[i] = prevV[i]->_nextV[i];prevV[i]->_nextV[i] = newNode;}}int randomLevel(){Node* cur = _head;srand(time(NULL));int level= 1;while(rand() <= RAND_MAX*_p && level < _maxLevel) { level++;}return level;}bool erase(int num){vector<Node*> prevV = findPervV(num);if(prevV[0]->_nextV[0] == nullptr || prevV[0]->_nextV[0]->_data != num){return false;}else{Node* del = prevV[0]->_nextV[0];for(int i = 0;i < del->_nextV.size();i++){prevV[i]->_nextV[i] = del->_nextV[i];}delete del;int index = _head->_nextV.size() -1;while (index >= 0) {if(_head->_nextV[index] == nullptr) {index--;}else {break;}	}return true;}}void print(){Node* cur = _head->_nextV[0];while(cur != nullptr){			cout << cur->_data << "->";	cur = cur->_nextV[0];}cout << "NULL" << endl;}};int main()
{Skiplist list;	list.add(1);list.add(3);list.add(6);cout << list.search(6) << endl;list.erase(9);list.erase(6);cout << list.search(6) << endl;list.print();return 0;
}
http://www.yayakq.cn/news/916576/

相关文章:

  • 淄博网站制作企业高端汽车网站建设开题报告
  • 微网站开发 课程标准合肥做网站建设
  • 关键词设定在网站上wordpress+左侧菜单
  • 辽宁省住房和城乡建设厅网站打不开网站设计的目的和功能
  • 有了网站源码怎么做app北京网站建设方案系统
  • 网站建设项目登记表番禺外贸型网站建设
  • 介绍网站ppt该怎么做公司网站建设应注意什么
  • 湖南建设监理官方网站网站整合营销推广
  • 网站建设报价单 非常好用的报价模板.docwordpress 手册 chm
  • 网站图片上传功能怎么做深圳市住房建设部网站
  • 丰台网站制作wordpress 七牛视频播放
  • 备案网站名称怎么写个人江西省赣州市地图
  • 网站字体特效代码最美情侣高清视频播放
  • 网络网站制作凡科互动游戏怎么破解
  • 秦皇岛网站设计制作怎么避免网站开发后门
  • 微信网站全称大气宽屏网站模板企业源码带后台
  • 知名的咨询行业网站制作做电子手抄报的网站
  • 建设企业网站可信度网站建设公司架构
  • 网站用自己的电脑做服务器国外网站注册软件
  • 河北省网站备案步骤二人对战的微信小程序
  • 太原正规的做定制网站制作杭州优化建筑设计
  • 江苏建设工程交易信息网站科技馆网站建设方案
  • 怎么做扒代码网站濮阳网站建设熊掌网络
  • 企业自有网站北京天奕时代创意设计有限公司
  • 建设厅证书查询网站石家庄网络关键词排名
  • 做网站jw100网站访问流程设计
  • 专业app制作平台seo关键词首页排名代发
  • 公司网站建设文案做网站用别人的源码可以吗
  • 攸县网站建设网站开发项目报价方案
  • 贵州省建设厅考试网站哈尔滨学网页设计