基于单向链表的队列的实现
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 }
以上是关于基于单向链表的队列的实现的主要内容,如果未能解决你的问题,请参考以下文章