力扣1206--跳表

1206. 设计跳表 - 力扣(LeetCode)

挑战一下hard,果然难搞

参考 跳表的原理与实现 [图解]_跳表实现-CSDN博客

代码如下:

cpp 复制代码
struct Node{
    Node(Node* _right, Node* _down, int _val) :
        right(_right), down(_down), val(_val){}
    Node* right;
    Node* down;
    int val;
};//Node节点的类型,一个右指针,一个向下的指针
class Skiplist {
private:
    Node* head;
    const static int max_Level = 32;//最大层数
    vector<Node*> pathList;//插入节点的时候,遍历查找小于target的最后一个Node,存在pathList中
public:
    Skiplist() {
        head = new Node(NULL, NULL, -1);//创建一个头结点进来
        pathList.reserve(max_Level);//使用reserve提前分配空间,每次都自动扩展32个
    }
    
    bool search(int target) {
        Node* p = head;
        while(p)
        {

            while(p->right && p->right->val < target)
                p = p->right;
            if(!p->right || p->right->val > target)
                p = p->down;
            else
                return true;
        }
        return false;
    }
    
    void add(int num) {
        Node* p = head;
        pathList.clear();
        while(p)
        {
            //从左往右查找,直到不小于num为止
            while(p->right != NULL && p->right->val < num)
                p = p->right;
            pathList.push_back(p);
            p = p->down;
            /*
            //如果到达边界,往下一层找
            //这地方放在尾部主要是为了后边插入的时候,pop_back出来,
            //刚好是从最底层插入,然后再往上更新
            if(p->right != NULL && p->right->val > num)
            {
                //如果右节点的值域大于num,那么把它放入list尾部
                pathList.push_back(p);
                //更新p
                p = p->down;
            }
            //if(p->right == nullptr)这里是个错误,上边if代码执行之后,会执行这个if
            //上述代码会改变p的值,所以这里不判断p值,直接访问p->right会导致指针越界
            //如果是其他情况,把当前的p放入list尾部
            else
            {
                pathList.push_back(p);
                p = p->down;
            }*/
        }
        //第一次把插入的flag置为true,从最底层开始,肯定是要插入的。
        bool insert_Up = true;
        Node* downNode = nullptr;//用于记录更新此次插入后的节点,如果上层需要插节点,用此更新
        while(insert_Up && pathList.size() > 0)
        {
            Node* tmpNode = pathList.back();//拿到最后一个节点
            pathList.pop_back();//弹出
            //把新节点插入当前层
            //建立新节点,同时更新right和down
            Node* insert_Node = new Node(tmpNode->right, downNode, num);
            //把新节点插入层中
            tmpNode->right = insert_Node;
            insert_Up = (rand() & 1 ) == 0;//每次有50%的概率需要提取到上一层
        }
        //如果需要在最上一层加层
        if(insert_Up)
        {
            //创建一个新Node,right为head,down为上次的downNode
            Node* tmpNode = new Node(nullptr, nullptr, -1);
            tmpNode->right = head;
            tmpNode->down = downNode;
            //更新head
            head = tmpNode;
        }

    }
    
    bool erase(int num) {
        Node* p = head;
        bool seen = false;
        while(p)
        {
            while(p->right && p->right->val < num)
                p = p->right;
            if(!p->right || p->right->val > num)
                p = p->down;
            else
            {
                seen = true;
                p->right = p->right->right;
                p = p->down;//没有这一行也可以,有的话可以加快查询
            }
        }
        return seen;
    }
};
相关推荐
懒惰才能让科技进步35 分钟前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
Ni-Guvara1 小时前
函数对象笔记
c++·算法
测试19981 小时前
2024软件测试面试热点问题
自动化测试·软件测试·python·测试工具·面试·职场和发展·压力测试
泉崎1 小时前
11.7比赛总结
数据结构·算法
你好helloworld1 小时前
滑动窗口最大值
数据结构·算法·leetcode
AI街潜水的八角2 小时前
基于C++的决策树C4.5机器学习算法(不调包)
c++·算法·决策树·机器学习
白榆maple2 小时前
(蓝桥杯C/C++)——基础算法(下)
算法
JSU_曾是此间年少2 小时前
数据结构——线性表与链表
数据结构·c++·算法
sjsjs112 小时前
【数据结构-合法括号字符串】【hard】【拼多多面试题】力扣32. 最长有效括号
数据结构·leetcode
此生只爱蛋3 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法