博客
关于我
从redis源码看数据结构(一)链表
阅读量:267 次
发布时间:2019-02-28

本文共 8246 字,大约阅读时间需要 27 分钟。

从Redis源码看数据结构(一)链表

Redis数据类型

Redis的数据类型有5种:列表(list)、哈希表(hash)、集合(set)、字符串(String)、有序集合(zset)。

Redis底层列表实现

关于Redis列表底层实现src/adlist.c,adlist.h,源码可以在相应位置拉取。

链表底层数据结构

链表节点结构体定义:

typedef struct listNode {    // 前驱节点    struct listNode *prev;    // 后继节点    struct listNode *next;    // 值    void *value;} listNode;

链表结构体定义:

typedef struct list {    // 表头指针    listNode *head;    // 表尾指针    listNode *tail;    // 节点数量    unsigned long len;    // 复制函数    void *(*dup)(void *ptr);    // 释放函数    void (*free)(void *ptr);    // 比对函数    int (*match)(void *ptr, void *key);} list;

链表迭代器结构体定义:

typedef struct listIter {    // 下一节点    listNode *next;    // 迭代方向    int direction;} listIter;

Redis双向链表操作

新建链表

list *listCreate(void) {    struct list *list;    if ((list = zmalloc(sizeof(*list))) == NULL) {        return NULL;    }    list->head = list->tail = NULL;    list->len = 0;    list->dup = NULL;    list->free = NULL;    list->match = NULL;    return list;}

删除链表

void listRelease(list *list) {    unsigned long len;    listNode *current, *next;    current = list->head;    len = list->len;    while (len--) {        next = current->next;        if (list->free) {            list->free(current->value);        }        zfree(current);        current = next;    }    zfree(list);}

添加头结点

list *listAddNodeHead(list *list, void *value) {    listNode *node;    if ((node = zmalloc(sizeof(*node))) == NULL) {        return NULL;    }    node->value = value;    if (list->len == 0) {        list->head = list->tail = node;        node->prev = node->next = NULL;    } else {        node->prev = NULL;        node->next = list->head;        list->head->prev = node;        list->head = node;    }    list->len++;    return list;}

添加尾结点

list *listAddNodeTail(list *list, void *value) {    listNode *node;    if ((node = zmalloc(sizeof(*node))) == NULL) {        return NULL;    }    node->value = value;    if (list->len == 0) {        list->head = list->tail = node;        node->prev = node->next = NULL;    } else {        node->prev = list->tail;        node->next = NULL;        list->tail->next = node;        list->tail = node;    }    list->len++;    return list;}

在指定节点前或后插入节点

list *listInsertNode(list *list, listNode *old_node, void *value, int after) {    listNode *node;    if ((node = zmalloc(sizeof(*node))) == NULL) {        return NULL;    }    node->value = value;    if (after) {        node->prev = old_node;        node->next = old_node->next;        if (list->tail == old_node) {            list->tail = node;        }    } else {        node->next = old_node;        node->prev = old_node->prev;        if (list->head == old_node) {            list->head = node;        }    }    if (node->prev != NULL) {        node->prev->next = node;    }    if (node->next != NULL) {        node->next->prev = node;    }    list->len++;    return list;}

删除节点

void listDelNode(list *list, listNode *node) {    if (node->prev != NULL) {        node->prev->next = node->next;    } else {        list->head = node->next;    }    if (node->next != NULL) {        node->next->prev = node->prev;    } else {        list->tail = node->prev;    }    if (list->free) {        list->free(node->value);    }    zfree(node);    list->len--;}

获取节点

listNode *listIndex(list *list, long index) {    listNode *n;    if (index < 0) {        index = (-index) - 1;        n = list->tail;        while (index-- && n) {            n = n->prev;        }    } else {        n = list->head;        while (index-- && n) {            n = n->next;        }    }    return n;}

链表迭代器获取当前节点

listNode *listNext(listIter *iter) {    listNode *current = iter->next;    if (current != NULL) {        if (iter->direction == AL_START_HEAD) {            iter->next = current->next;        } else {            iter->next = current->prev;        }    }    return current;}

Java链表实现

单链表

public class MyList {    private static class Node {        private Node next;        private int value;        public Node(int value) {            this.value = value;        }    }    private Node head;    private int size;    public MyList() {        head = null;        size = 0;    }    public void addFirst(int value) {        Node node = new Node(value);        node.next = head;        if (head == null) {            head = node;            tail = node;        } else {            head.prev = node;        }        size++;    }    public void addLast(int value) {        Node node = new Node(value);        if (head == null) {            head = node;            tail = node;        } else {            tail.next = node;            node.prev = tail;        }        size++;    }    public void remove(int index) {        if (index < 0 || index > size) {            throw new IllegalArgumentException("index greater list.size");        }        if (head == null) {            throw new IllegalArgumentException("list is null list");        }        if (index == 0) {            Node deleteNode = head;            head = head.next;            deleteNode.next = null;            size--;        } else {            Node cur = head;            for (int i = 0; i < index - 1; i++) {                cur = cur.next;            }            Node deleteNode = cur.next;            cur.next = deleteNode.next;            deleteNode.next = null;            size--;        }    }    public boolean contains(int value) {        Node cur = head;        while (cur != null) {            if (cur.value == value) {                return true;            }            cur = cur.next;        }        return false;    }}

双向链表

public class MyLinkedList {    private Node head;    private Node tail;    private int size;    private class Node {        private Node pre;        private Node next;        private int value;        public Node(int value) {            this.value = value;        }    }    public MyLinkedList() {        head = null;        tail = null;        size = 0;    }    public void addFirst(int value) {        Node node = new Node(value);        Node head = this.head;        this.head = node;        if (head == null) {            this.tail = node;        } else {            head.pre = node;        }        node.next = head;        size++;    }    public void addLast(int value) {        Node node = new Node(value);        Node tail = this.tail;        this.tail = node;        if (this.head == null) {            this.head = node;        } else {            tail.next = node;        }        node.pre = tail;        size++;    }    public void remove(int index) {        if (index < 0 || index > size) {            throw new IllegalArgumentException("index greater list.size");        }        if (head == null) {            throw new IllegalArgumentException("list is null list");        }        if (index == 0) {            Node deleteNode = head;            head = head.next;            deleteNode.next = null;            size--;        } else if (index == size) {            Node deleteNode = tail;            tail = tail.pre;            deleteNode.pre = null;            size--;        } else {            Node cur = head;            for (int i = 0; i < index - 1; i++) {                cur = cur.next;            }            Node deleteNode = cur.next;            cur.next = deleteNode.next;            deleteNode.next = null;            deleteNode.pre = cur;            size--;        }    }}

测试代码

public static void main(String[] args) {    MyList myList = new MyList();    for (int i = 0; i < 5; i++) {        myList.addLast(i);    }    System.out.println(myList.size);    System.out.println(myList.contains(5));    System.out.println(myList.contains(2));    myList.add(1, 5);    System.out.println(myList.contains(5));    System.out.println(myList.head.value);    myList.add(0, 9);    System.out.println(myList.head.value);}
public static void main(String[] args) {    MyLinkedList myLinkedList = new MyLinkedList();    for (int i = 0; i < 5; i++) {        myLinkedList.addLast(i);    }    System.out.println(myLinkedList.contains(2));    System.out.println(myLinkedList.head.value);    System.out.println(myLinkedList.tail.value);    myLinkedList.remove(3);    System.out.println(myLinkedList.contains(3));    myLinkedList.remove(0);    System.out.println(myLinkedList.head.value);}

转载地址:http://yxvp.baihongyu.com/

你可能感兴趣的文章
OpenCV与AI深度学习 | 实战—使用YOLOv8图像分割实现路面坑洞检测(步骤 + 代码)
查看>>
OpenCV与AI深度学习 | 实战篇——基于YOLOv8和OpenCV实现车速检测(详细步骤 + 代码)
查看>>
OpenCV与AI深度学习 | 实战|OpenCV实时弯道检测(详细步骤+源码)
查看>>
OpenCV与AI深度学习 | 实践教程|旋转目标检测模型-TensorRT 部署(C++)
查看>>
OpenCV与AI深度学习 | 工业缺陷检测中数据标注需要注意的几个事项
查看>>
OpenCV与AI深度学习 | 干货 | 深度学习模型训练和部署的基本步骤
查看>>
OpenCV与AI深度学习 | 手把手教你用Python和OpenCV搭建一个半自动标注工具(详细步骤 + 源码)
查看>>
OpenCV与AI深度学习 | 水下检测+扩散模型:或成明年CVPR最大惊喜!
查看>>
OpenCV与AI深度学习 | 深度学习检测小目标常用方法
查看>>
OpenCV与AI深度学习 | 超越YOLOv10/11、RT-DETRv2/3!中科大D-FINE重新定义边界框回归任务
查看>>
OpenCV与AI深度学习 | 高效开源的OCR工具:Surya-OCR介绍与使用
查看>>
OpenCV与AI深度学习|16个含源码和数据集的计算机视觉实战项目(建议收藏!)
查看>>
Opencv中KNN背景分割器
查看>>
OpenCV中基于已知相机方向的透视变形
查看>>
OpenCV中的监督学习
查看>>
opencv中读写视频
查看>>
OpenCV中遇到Microsoft C++ 异常 cv::Exception
查看>>
opencv之cv2.findContours和drawContours(python)
查看>>
opencv之namedWindow,imshow出现两个窗口
查看>>
opencv之模糊处理
查看>>