ds通用queue(1.0)

又有好长一段时间没有更新这个话题了, 今天我们开始来讲解通用queue的实现。

像前面讲解的其他数据结构一样, 我们还是先来回忆一下简单的queue的实现, 我们都知道queue是一种FIFO的数据结构, 就像我们在车站买车票一样的, 排在前面的人先买到车票, 然后出队列。我们先实现一个简单的queue来复习一下利用C语言该怎么写这个数据结构呢? 就规定写一个保存int类型数据的queue吧。

我们先定义出该int类型的queue的基本操作接口, 具体操作接口如下:

struct c_queue;

extern struct c_queue* c_queue_new(void);

extern void c_queue_free(struct c_queue** cq);

extern int c_queue_empty(struct c_queue* self);

extern size_t c_queue_size(struct c_queue* self);

extern int c_queue_push(struct c_queue* self, int data);

extern int c_queue_pop(struct c_queue* self);

extern int c_queue_top(struct c_queue* self);

有了这些操作接口, 那我在实现的时候该怎么做到数据的先进先出呢? 其实也很简单, 我们只需要定义一个简单的链表结构, 就可以很方便的管理我们的数据了, 关键是实现数据的先进先出, 那该怎么实现呢? 

我们都知道利用单链表的话, 实现从头插入和从头部删除是很方便的, 这个就很类似stack的原理了, 但是这里queue是要实现从尾部插入。或许有的同学已经想到了, 对, 我们可以使用双向链表。这个方案确实不错, 但是管理一个简单的queue是不是有点费力了呢? 

其实也很简单, 我们可以再保留一个单链表的尾指针就行了啊, 这样我们就可以从单链表的尾部插入数据, 而从其头部取出数据了。

在queue的实现文件里面, 我们定义其结构如下:

struct __queue_node {

    int _data;

    struct __queue_node* _next;

};

struct c_queue {

    size_t _size;

    struct __queue_node* _head;

    struct __queue_node* _tail;

};

有了queue的具体结构, 这个_head用来保存我们链表的头指针, 而_tail用来保存链表的尾指针, 这样就很简单的实现了链表的尾插和头出。

有了这两个结构, 相信实现该queue的各个操作接口就很简单了吧, 那么我该出其具体的实现方法如下:

static inline struct __queue_node* _queue_new_node(int _x) {

    struct __queue_node* node = NULL;

    size_t size = sizeof(struct __queue_node);

    node = (struct __queue_node*)c_malloc(size);

    if (NULL != node)

        node->_data = _x;

    return node;

}

static inline void _queue_clear(struct c_queue* _p) {

    struct __queue_node* n = NULL;

    if (NULL != _p) {

        while (NULL != _p->_head) {

            n = _p->_head;

            _p->_head = _p->_head->_next;

            c_free(n);

        }

        _p->_size = 0;

    }

}

struct c_queue* c_queue_new(void) {

    struct c_queue* self = NULL;

    size_t size = sizeof(struct c_queue);

    self = (struct c_queue*)c_malloc(size);

    return self;

}

void c_queue_free(struct c_queue** cq) {

    _queue_clear(*cq);

    c_free(*cq);

}

int c_queue_empty(struct c_queue* self) {

    return (NULL != self ? NULL == self->_head : 0);

}

size_t c_queue_size(struct c_queue* self) {

    return (NULL != self ? self->_size : 0);

}

int c_queue_push(struct c_queue* self, int data) {

    struct __queue_node* node = _queue_new_node(data);

    if (NULL != self) {

        if (NULL == self->_head)

            self->_head = self->_tail = node;

        self->_tail->_next = node;

        self->_tail = node;

        self->_size++;

        return 0;

    }

    return -1;

}

int c_queue_pop(struct c_queue* self) {

    struct __queue_node* node = NULL;

    if (NULL != self) {

        if (NULL != self->_head) {

            node = self->_head;

            self->_head = self->_head->_next;

            c_free(node);

            self->_size--;

        }

        return 0;

    }

    return -1;

}

int c_queue_top(struct c_queue* self) {

    struct __queue_node* node = NULL;

    if (NULL != self)

        node = self->_head;

    return (NULL != node ? node->_data : -0x7fffffff);

}

好了通过对这个int类型的queue的实现相信大家对queue已经有所了解了吧, 今天就先到这里吧, 下次我们开始正式实现通用的queue操作接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值