数据结构_队列(基于顺序表和链表)

    队列是只允许在一端进行数据操作,在另一端进行删除数据的一种特殊线性表,进行插入操作(入队列)一端的称为队尾,进行删除操作(出队列)的一端称为队头,队列具有先进先出的特性。队列和栈相似,基于顺序表或链表实现,限制对顺序表、链表的操作,减少出错的可能性。
     
    队列按用途可分为三类:
  • 普通队列
  • 消息队列
  • 优先级队列

基于顺序表、链表实现队列的基本操作:
    队列的基本操作:入队列、出队列、取队首元素,如下所示:
    

一、顺序表实现队列
    用定长数组实现队列,要对队首和队尾操作,需要搬运数组元素,效率较低,可以记住队首、队尾的位置。进行操作入队列操作时,修改队尾的位置,队尾到达数组上限时,先确定数组是否还有空间,有的话移动到数组头部;出队列修改队首的位置,如果队首到达数组上限,让队首回到数组头部。

以下为代码实现:
// 头文件及结构体声明
  1 #pragma once                                                                                                                      
  2                                                                                                                                   
  3 #include<stdio.h>                                                                                                                 
  4 #include<stdlib.h>                                                                                                                
  5 #include<string.h>                                                                                                                
  6 #include<stddef.h>                                                                                                                
  7                                                                                                                                   
  8 typedef char SeqListQueueType;                                                                                                    
  9                                                                                                                                   
10 #define SeqListQueueMaxSize 1000                                                                                                  
11                                                                                                                                   
12 typedef struct SeqListQueue{                                                                                                      
13     SeqListQueueType data[SeqListQueueMaxSize];                                                                                   
14     size_t head;                                                                                                                  
15     size_t tail;                                                                                                                  
16     size_t size;                                                                                                                  
17 }SeqListQueue;

1.队列初始化、销毁
// 初始化
  3 void SeqListQueueInit(SeqListQueue* queue)                                                                                        
  4 {                                                                                                                                 
  5     if(queue == NULL){                                                                                                            
  6         return;                                                                                                                   
  7     }                                                                                                                             
  8     queue->size = 0;                                                                                                              
  9     queue->head = 0;                                                                                                              
10     queue->tail = 0;                                                                                                              
11     return;                                                                                                                       
12 }                                                                                                                                 

//  销毁                                                                                                                            
14 void SeqListQueueDestory(SeqListQueue* queue)                                                                                     
15 {                                                                                                                                 
16     if(queue == NULL){                                                                                                            
17         return;                                                                                                                   
18     }                                                                                                                             
19     queue->size = 0;                                                                                                              
20     queue->head = 0;                                                                                                              
21     queue->tail = 0;                                                                                                              
22     queue = NULL;                                                                                                                 
23     return;                                                                                                                       
24 }

2.入队列、出队列
// 入队列
26 void SeqListQueuePush(SeqListQueue* queue, SeqListQueueType value)                                                                
27 {                                                                                                                                 
28     if(queue == NULL){                                                                                                            
29         return;                                                                                                                   
30     }                                                                                                                             
31     if(queue->size >= SeqListQueueMaxSize){                                                                                       
32         // 队列已满                                                                                                               
33         return;                                                                                                                   
34     }                                                                                                                             
35     if(queue->tail > SeqListQueueMaxSize){        // 修改 tail                                                                                 
36         queue->tail = 0;                                                                                                          
37     }                                                                                                                             
38     // 元素入队列,tail 值+1,如果 tail 到达数组尾部,让 tail 回到数组的头部                                                                                           
39     queue->data[queue->tail ++] = value;        // 入队列                                          
40     queue->size ++;                                                                                                               
41     return;                                                                                                                       
42 }                                                                                                                                 

// 出队列                                                                                                                            
44 void SeqListQueuePop(SeqListQueue* queue)                                                                                         
45 {                                                                                                                                 
46     if(queue == NULL){                                                                                                            
47         return;                                                                                                                   
48     }                                                                                                                             
49     if(queue->size == 0){                                                                                                         
50         // 空队列                                                                                                                 
51         printf("空队列.\n");                                                                                                      
52         return;                                                                                                                   
53     }                                                                                                                             
54     if(queue->head > SeqListQueueMaxSize){                                                                                        
55         queue->head = 0;                                                                                                          
56     }                                                                                                                             
57     // 元素出队列,head +1 ,如果 head 到数组尾部,让 head 回到数组的头部                                                         
58     queue->head ++;                                                                                                               
59     queue->size --;                                                                                                               
60     return;                                                                                                                       
61 }

3.取队首元素
63 int SeqListQueueFront(SeqListQueue* queue, SeqListQueueType* front)                                                               
64 {                                                                                                                                 
65     if(queue == NULL || front == NULL){                                                                                           
66         return 0;                                                                                                                 
67     }                                                                                                                             
68     if(queue->size == 0){         // 空队列                                                                                                
69         return 0;                                                                                                                 
70     }                                                                                                                             
71     *front = queue->data[queue->head];                                                                                            
72     return 1;                                                                                                                     
73 }

二、链表实现队列
    用带有头结点的单向链表实现。进行入队列操作时,采用尾插,遍历链表;出队列时,采用头删。以下为代码实现:
// 头文件及结构体声明
  1 #pragma once                                                                                                                      
  2                                                                                                                                   
  3 #include<stdio.h>                                                                                                                 
  4 #include<stdlib.h>                                                                                                                
  5 #include<string.h>                                                                                                                
  6 #include<stddef.h>                                                                                                                
  7                                                                                                                                   
  8 typedef char LinkQueueType;                                                                                                       
  9                                                                                                                                   
10 typedef struct LinkQueue{                                                                                                         
11     LinkQueueType data;                                                                                                           
12     struct LinkQueue* next;                                                                                                       
13 }LinkQueue;

1.队列初始化、销毁
// 初始化
  3 void LinkQueueInit(LinkQueue** queue)                                                                                             
  4 {                                                                                                                                 
  5     if(queue == NULL){                                                                                                            
  6         return;                                                                                                                   
  7     }                                                                                                                             
  8     *queue = (LinkQueue*)malloc(sizeof(LinkQueue));                                                                               
  9     (*queue)->data = 0;                                                                                                           
10     (*queue)->next = NULL;                                                                                                        
11     return;                                                                                                                       
12 }                                                                                                                                 

//  销毁                                                                                                                            
14 void LinkQueueDestroy(LinkQueue** queue)                                                                                          
15 {                                                                                                                                 
16     if(queue == NULL){                                                                                                            
17         return;                                                                                                                   
18     }                                                                                                                             
19     free(*queue);                                                                                                                 
20     *queue = NULL;                                                                                                                
21     return;                                                                                                                       
22 }

2.入队列、出队列
// 创建结点
24 LinkQueue* LinkQueueCreateNode(LinkQueueType value)                                                                               
25 {                                                                                                                                 
26     LinkQueue* new_node = (LinkQueue*)malloc(sizeof(LinkQueue));                                                                  
27     new_node->data = value;                                                                                                       
28     new_node->next = NULL;                                                                                                        
29     return new_node;                                                                                                              
30 }                                                                                                                                 

// 销毁结点                                                                                                                              
32 void LinkQueueDestroyNode(LinkQueue* pos)                                                                                         
33 {                                                                                                                                 
34     if(pos){                                                                                                                      
35         free(pos);                                                                                                                
36         return;                                                                                                                   
37     }                                                                                                                             
38 }

// 入队列
40 void LinkQueuePush(LinkQueue* queue, LinkQueueType value)                                                                         
41 {                                                                                                                                 
42     if(queue == NULL){                                                                                                            
43         return;                                                                                                                   
44     }                                                                                                                             
45     LinkQueue* new_node = LinkQueueCreateNode(value);                                                                             
46     if(queue->next == NULL){                                                                                                      
47         queue->next = new_node;                                                                                                   
48         return;                                                                                                                   
49     }                                                                                                                             
50     LinkQueue*cur = queue->next;                                                                                                  
51     while(cur->next != NULL){                                                                                                     
52         cur = cur->next;                                                                                                          
53     }                                                                                                                             
54     cur->next = new_node;                                                                                                         
55     return;                                                                                                                       
56 }

// 出队列
58 void LinkQueuePop(LinkQueue* queue)                                                                                               
59 {                                                                                                                                 
60     if(queue == NULL){                                                                                                            
61         return;                                                                                                                   
62     }                                                                                                                             
63     if(queue->next == NULL){                                                                                                      
64         return;                                                                                                                   
65     }                                                                                                                             
66     LinkQueue* tmp = queue->next;                                                                                                 
67     queue->next = tmp->next;                                                                                                      
68     LinkQueueDestroyNode(tmp);                                                                                                    
69     return;                                                                                                                       
70 }  

3.取队首元素
72 int LinkQueueFront(LinkQueue* queue, LinkQueueType* front)                                                                        
73 {                                                                                                                                 
74     if(queue == NULL || front == NULL){                                                                                           
75         return 0;                                                                                                                 
76     }                                                                                                                             
77     if(queue->next == NULL){                                                                                                      
78         return 0;                                                                                                                 
79     }                                                                                                                             
80     *front = queue->next->data;                                                                                                   
81     return 1;                                                                                                                     
82 }

三、顺序表、链表实现队列差异
    顺序表:定长,对队列进行入队列操作的时候,需要判断队列是否已满,保存队首、队尾的下标,简化了队列操作,时间复杂度为 O(1)。
    链表:动态申请内存,对队列进行入队列操作时,需要遍历链表找到队尾元素进行入队列,时间复杂度为 O(n)。



猜你喜欢

转载自blog.csdn.net/Cherubim1/article/details/80247611