基于单向链表的队列的实现

Posted chenweilin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于单向链表的队列的实现相关的知识,希望对你有一定的参考价值。

1.单链表实现

slist.h

 1 #ifndef _SLIST_H
 2 #define _SLIST_H
 3 
 4 typedef struct _slist_node
 5 {
 6     struct _slist_node *p_next; /* 指向下一个结点的指针 */
 7 }slist_node_t;
 8 
 9 typedef slist_node_t slist_head_t;
10 typedef int (*slist_node_process_t)(void *p_arg, slist_node_t *p_node);
11 
12 int slist_init(slist_head_t *p_head);
13 int slist_add(slist_head_t *p_head, slist_node_t *p_pos, slist_node_t *p_node);
14 int slist_add_tail(slist_head_t *p_head, slist_node_t *p_node);
15 int slist_add_head(slist_head_t *p_head, slist_node_t *p_node);
16 int slist_del(slist_head_t *p_head, slist_node_t *p_node);
17 
18 slist_node_t *slist_prev_get(slist_head_t *p_head, slist_node_t *p_pos);
19 slist_node_t *slist_next_get(slist_head_t *p_head, slist_node_t *p_pos);
20 slist_node_t *slist_tail_get(slist_head_t *p_head);
21 slist_node_t *slist_begin_get(slist_head_t *p_head);
22 slist_node_t *slist_end_get (slist_head_t *p_head);
23 int slist_foreach(slist_head_t *p_head,
24                   slist_node_process_t pfn_node_process,
25                   void *p_arg);
26 
27 #endif

slist.c

 1 #include "slist.h"
 2 #include <stdlib.h>
 3 
 4 int slist_init(slist_head_t *p_head)
 5 {
 6     if (p_head == NULL)
 7     {
 8         return -1;
 9     }
10     p_head->p_next = NULL;
11     return 0;
12 }
13 
14 int slist_add(slist_head_t *p_head, slist_node_t *p_pos, slist_node_t *p_node)
15 {
16     p_node->p_next = p_pos->p_next;
17     p_pos->p_next = p_node;
18     return 0;
19 }
20 
21 int slist_add_tail(slist_head_t *p_head, slist_node_t *p_node)
22 {
23     slist_node_t *p_tmp = slist_tail_get(p_head); /* 找到尾结点 */
24     return slist_add(p_head, p_tmp, p_node); /* 添加结点至尾结点之后 */
25 }
26 
27 int slist_add_head(slist_head_t *p_head, slist_node_t *p_node)
28 {
29     return slist_add(p_head, p_head, p_node); /* 添加结点至头结点之后 */
30 }
31 
32 int slist_del(slist_head_t *p_head, slist_node_t *p_node)
33 {
34     slist_node_t *p_prev = slist_prev_get(p_head, p_node); /* 找到待删除结点的上一个结点 */
35     if (p_prev) 
36     {
37         p_prev->p_next = p_node->p_next;
38         p_node->p_next = NULL;
39         return 0;
40     }
41     return -1;
42 }
43 
44 slist_node_t *slist_prev_get(slist_head_t *p_head, slist_node_t *p_pos)
45 {
46     slist_node_t *p_tmp = p_head;
47     while ((p_tmp != NULL) && (p_tmp->p_next != p_pos))
48     {
49         p_tmp = p_tmp->p_next;
50     }
51     return p_tmp;    
52 }
53 
54 slist_node_t *slist_next_get(slist_head_t *p_head, slist_node_t *p_pos)
55 {
56     if (p_pos) 
57     {
58         return p_pos->p_next;
59     }
60     return NULL;
61 }
62 
63 slist_node_t *slist_tail_get(slist_head_t *p_head)
64 {
65     return slist_prev_get(p_head, NULL);
66 }
67 
68 slist_node_t *slist_begin_get(slist_head_t *p_head)
69 {
70     return slist_next_get(p_head, p_head);
71 }
72 
73 slist_node_t *slist_end_get(slist_head_t *p_head)
74 {
75     return NULL;
76 }
77 
78 int slist_foreach(slist_head_t *p_head,
79                   slist_node_process_t pfn_node_process,
80                   void *p_arg)
81 {
82     slist_node_t *p_tmp, *p_end;
83     int ret;
84 
85     if ((p_head == NULL) || (pfn_node_process == NULL))
86     {
87         return -1;
88     }
89     p_tmp = slist_begin_get(p_head);
90     p_end = slist_end_get(p_head);
91     while (p_tmp != p_end)
92     {
93         ret = pfn_node_process(p_arg, p_tmp);
94         if (ret < 0) 
95             return ret; /* 不再继续遍历 */
96         p_tmp = slist_next_get(p_head, p_tmp); /* 继续下一个结点 */
97     }
98     return 0;
99 }

2.队列的实现

queue.h

 1 #ifndef _QUEUE_H
 2 #define _QUEUE_H
 3 
 4 #include <stdbool.h>
 5 #include <stddef.h>
 6 
 7 typedef int queueElementT;
 8 typedef struct queueCDT * queueADT;
 9 
10 queueADT newQueue(void);
11 void freeQueue(queueADT queue);
12 bool inQueue(queueADT queue, queueElementT value);
13 bool outQueue(queueADT queue, queueElementT *p_alue);
14 bool queueIsEmpty(queueADT queue);
15 bool queueIsFull(queueADT queue);
16 size_t getQueueLength(queueADT queue);
17 
18 #endif

queue_slist.c

 1 #include "queue.h"
 2 #include <stdlib.h>
 3 #include "slist.h"
 4 
 5 #define MAXQSIZE 100
 6 struct queueCDT 
 7 {
 8     slist_head_t list_head; /* 链表头结点 */
 9     slist_node_t *p_rear; /* 指向队列的尾结点 */
10 };
11 
12 typedef struct _queue_node_t
13 {
14     slist_node_t node;
15     queueElementT data;
16 } queue_node_t;
17 
18 queueADT newQueue(void)
19 {
20     queueADT queue;
21     queue = (queueADT)malloc(sizeof(struct queueCDT));
22     slist_init(&queue->list_head);
23     queue->p_rear = &(queue->list_head);
24     return queue;
25 }
26 
27 void freeQueue(queueADT queue)
28 {
29     while (!queueIsEmpty(queue))
30     {
31         slist_node_t *p_node = slist_begin_get(&queue -> list_head);
32         slist_del(&queue -> list_head, p_node);
33         free((queue_node_t *)p_node);
34     }
35     free(queue);
36 }
37 
38 bool inQueue(queueADT queue, queueElementT value)
39 {
40     if(queueIsFull(queue)) 
41     {
42         return false;
43     }
44     queue_node_t *p_node = (queue_node_t *)malloc(sizeof(queue_node_t));
45     p_node -> data = value;
46     slist_add(&queue->list_head, queue->p_rear,&(p_node->node));
47     queue->p_rear = queue->p_rear->p_next;
48     return true;
49 }
50 
51 bool outQueue(queueADT queue, queueElementT *p_value)
52 {
53     if(queueIsEmpty(queue)) 
54     {
55         return false;
56     }
57     slist_node_t *p_node = slist_begin_get(&queue -> list_head);
58     *p_value = ((queue_node_t *)p_node) -> data;
59     slist_del(&queue -> list_head, p_node);
60     free(p_node);
61     return true;
62 }
63 
64 bool queueIsEmpty(queueADT queue)
65 {
66     return (slist_begin_get(&queue -> list_head) == slist_end_get(&queue -> list_head));
67 }
68 
69 bool queueIsFull(queueADT queue)
70 {
71     /* 链队列不会满 */
72     return false;
73 }
74 
75 static int _numElems_node(void *p_arg, slist_node_t *p_node)
76 {
77     (*(size_t *)p_arg)++;
78     return 0;
79 }
80 
81 size_t getQueueLength(queueADT queue)
82 {
83     size_t count = 0;
84     slist_foreach(&queue->list_head, _numElems_node, &count);
85     return count;
86 }

3.Demo

main.c

 1 #include <stdio.h>
 2 #include "queue.h"
 3 
 4 int main(int argc, char *argv[])
 5 {
 6     queueADT queue;
 7     int temp, i;
 8 
 9     queue = newQueue();
10     for(i = 0; i < 16; i++) 
11     {
12         inQueue(queue, i);
13     }
14     printf("The length is %d
", (int)getQueueLength(queue));
15     while (!queueIsEmpty(queue)) 
16     {
17         outQueue(queue, &temp);
18         printf("%d ", temp);
19     }
20     freeQueue(queue);
21     return 0;
22 }

 

以上是关于基于单向链表的队列的实现的主要内容,如果未能解决你的问题,请参考以下文章

队列(链式队列)

C语言反转单向链表的代码

链表的java实现(单向双向链表,单向链表的反转)

链表的java实现(单向双向链表,单向链表的反转)

数据结构《二》链表的实现

基于单向链表的后宫管理系统