力扣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;
    }
};
相关推荐
en.en..8 小时前
C语言核心解析:#define与typedef本质区别
开发语言·c++·算法
YonyouHRSaaS10 小时前
AI视频面试系统定义、功能作用、品牌推荐、选择攻略
人工智能·面试·职场和发展·ai面试·视频面试·ai视频面试
zihan51810 小时前
理论:构建“基于客观事实、可量化、闭环自给自足”的个人操作系统
笔记·职场和发展·学习方法
wabs66611 小时前
关于二叉树【429.N叉树的层序遍历的思考】
数据结构·c++·算法·leetcode·二叉树
hetao173383711 小时前
2026-09-08 hetao1733837 的刷题记录
c++·算法
C++ 老炮儿的技术栈11 小时前
MFC CPtrArray的用法
开发语言·数据结构·c++·算法·mfc·c
小鱼爱吃草灬灬11 小时前
实时面试辅助排查清单:音频来源、问题输入与上下文
面试·职场和发展·音视频
weixin_4462608511 小时前
CABAL:用于追踪同行评审中合谋投标影响的多智能体仿真框架
人工智能·算法·机器学习
不会就选b11 小时前
算法日常・每日刷题--<贪心>6
数据结构·算法·leetcode
青山木12 小时前
Hot 100 --- 跳跃游戏 II
java·数据结构·算法·leetcode·贪心算法