本文共 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/