博客
关于我
从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/

你可能感兴趣的文章
np.arange()和np.linspace()绘制logistic回归图像时得到不同的结果?
查看>>
np.power的使用
查看>>
NPM 2FA双重认证的设置方法
查看>>
npm build报错Cannot find module ‘webpack/lib/rules/BasicEffectRulePlugin‘解决方法
查看>>
npm build报错Cannot find module ‘webpack‘解决方法
查看>>
npm ERR! ERESOLVE could not resolve报错
查看>>
npm ERR! fatal: unable to connect to github.com:
查看>>
npm ERR! Unexpected end of JSON input while parsing near '...on":"0.10.3","direc to'
查看>>
npm ERR! Unexpected end of JSON input while parsing near ‘...“:“^1.2.0“,“vue-html-‘ npm ERR! A comp
查看>>
npm error Missing script: “server“npm errornpm error Did you mean this?npm error npm run serve
查看>>
npm error MSB3428: 未能加载 Visual C++ 组件“VCBuild.exe”。要解决此问题,1) 安装
查看>>
npm install CERT_HAS_EXPIRED解决方法
查看>>
npm install digital envelope routines::unsupported解决方法
查看>>
npm install 卡着不动的解决方法
查看>>
npm install 报错 EEXIST File exists 的解决方法
查看>>
npm install 报错 ERR_SOCKET_TIMEOUT 的解决方法
查看>>
npm install 报错 Failed to connect to github.com port 443 的解决方法
查看>>
npm install 报错 fatal: unable to connect to github.com 的解决方法
查看>>
npm install 报错 no such file or directory 的解决方法
查看>>
npm install 权限问题
查看>>