基础数据结构-用链表实现队列和栈

链表在memcached、redis中做为核心数据结构出现。相比数组,链表能动态增减容量,就比数组要灵活,而且hash表结构通常都使用链表进行数据存储git

完整案例代码已上传github: github.com/neatlife-le…github

队列

元素结构

对应代码以下redis

typedef struct _element {
    struct _element *previous;
    struct _element *next;
    void *value;
} element;
复制代码

队列结构

一个队列中包含多个元素,为了可以方便的获得这个队列头和尾,以及队列里的元素个数,使用这个queue结构来存放这些信息数组

对应代码以下数据结构

typedef struct _queue {
    element *head;
    element *end;
    size_t size;
} queue;
复制代码

新建队列

queue* new_queue(void *value) {
    element *item = (element *) malloc(sizeof(element));
    item->value = value;
    item->previous = NULL;
    item->next = NULL;
    
    queue *a_queue = (queue *) malloc(sizeof(queue));
    a_queue->head = item;
    a_queue->end = item;
    a_queue->size = 1;
    return a_queue;
}
复制代码
  1. 为元素分配内存空间,并获得指向这个元素内存空间的指针
  2. 为队列分配内存空间,并把队列头、尾指针指向上面建立的元素,由于这个队列里初始化的时候只有这一个元素
  3. 把队列大小设置为1

进队列

void push(queue *a_queue, void *value) {
    element *item = (element *) malloc(sizeof(element));
    item->value = value;
    
    item->previous = a_queue->end;
    item->next = NULL;
    
    a_queue->end->next = item;
    a_queue->end = item;
    a_queue->size = a_queue->size + 1;
}
复制代码

队列的特性是先进先出,通常出的时候都是拿链表的最后一个元素,进的时候就把新元素加到链表尾memcached

  1. 建立新元素,并把这个元素的next置为NULL
  2. 把新元素挂到链表尾
  3. 队列中的元素数量+1

出队列

element* pop(queue *a_queue) {
    element *item = a_queue->end;
    
    a_queue->end = a_queue->end->previous;
    item->previous = NULL;
    a_queue->end->next = NULL;
    
    a_queue->size = a_queue->size - 1;
    
    return item;
}
复制代码
  1. 取出队列的最后一个元素
  2. 队列的最后一个元素变成了倒数第二个元素
  3. 短掉取出的元素和队列的关系
  4. 队列中的元素数量-1

获取队列状态

void stats(queue *a_queue) {
    cout << "current queue size: " << a_queue->size << endl;
    
    cout << "current queue content: " << endl;
    element *item = a_queue->head;
    while (item) {
        cout << (size_t) item->value << endl;
        item = item->next;
    }
}
复制代码

测试脚本

queue* a_queue = new_queue((size_t *) 1)
push(a_queue, (size_t *) 2);

stats(a_queue);
element *item = pop(a_queue);
stats(a_queue);
cout << (size_t)item->value << endl;
复制代码

效果以下: 测试

能够看到出队列是从队列尾部出的

异常处理

出队列时可对a_queue->size进行判断,若是size等于0了,表示队列中已经没有数据了,就不能再执行出队列操做了ui

当出队列出到a_queue->size等于0时,须要清空队列的end、previous指针spa

栈和队列除了出栈操做不同,其它部分彻底一致,队列出队列的时候从尾部出,栈出栈的时候从头部出,核心代码以下3d

element* pop(stack *a_stack) {
    element *item = a_stack->head;
    
    a_stack->head = a_stack->head->next;
    item->next = NULL;
    a_stack->head->previous = NULL;
    
    a_stack->size = a_stack->size - 1;
    
    return item;
}
复制代码

一些注意的点

cpp指针初始化须要明确设置为NULL

参考资料

  1. www.zhihu.com/question/24…
相关文章
相关标签/搜索