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

你可能感兴趣的文章
netty 主要组件+黏包半包+rpc框架+源码透析
查看>>
Netty 异步任务调度与异步线程池
查看>>
Netty中集成Protobuf实现Java对象数据传递
查看>>
Netty事件注册机制深入解析
查看>>
Netty原理分析及实战(四)-客户端与服务端双向通信
查看>>
Netty客户端断线重连实现及问题思考
查看>>
Netty工作笔记0006---NIO的Buffer说明
查看>>
Netty工作笔记0007---NIO的三大核心组件关系
查看>>
Netty工作笔记0011---Channel应用案例2
查看>>
Netty工作笔记0013---Channel应用案例4Copy图片
查看>>
Netty工作笔记0014---Buffer类型化和只读
查看>>
Netty工作笔记0020---Selectionkey在NIO体系
查看>>
Vue踩坑笔记 - 关于vue静态资源引入的问题
查看>>
Netty工作笔记0025---SocketChannel API
查看>>
Netty工作笔记0027---NIO 网络编程应用--群聊系统2--服务器编写2
查看>>
Netty工作笔记0050---Netty核心模块1
查看>>
Netty工作笔记0057---Netty群聊系统服务端
查看>>
Netty工作笔记0060---Tcp长连接和短连接_Http长连接和短连接_UDP长连接和短连接
查看>>
Netty工作笔记0063---WebSocket长连接开发2
查看>>
Netty工作笔记0070---Protobuf使用案例Codec使用
查看>>