<数据结构> 队列Queue

一.队列Queue:先进先出 FIFO

1.队列有两个指针 一个是队首 一个是队尾 可以理解成链表的头删除和尾添加

2.存储方式:

①顺序存储 ②链式存储

3.顺序存储的应用:循环队列

(以下来自本人看过百度文库后的个人理解)

循环队列:开辟一个数组空间 把这个数组空间想象成一个首尾相连的圆环空间 存储在这个循环空间的队列就称为循环队列

循环队列存在一个问题就是假溢出 什么叫假溢出呢?

假溢出可以理解成:明明这个循环存储空间并没有满 但是却不让我们插入新的数据 造成一个假的溢出现象

用一个一维数组arr[m]来存储一个循环队列 这个循环队列的队列元素为m 元素下标是从0到m-1结束

队首为Head 队尾为Tail 队首指向队头元素的前一个位置 队尾指针就是指向队尾元素

当Head为-1时 说明这个队列是空的 当Tail为m-1的时候 说明这个队列是满的

由于队列的性质 是链表的头删除和尾添加 当Tail为m-1但是Head不等于-1的时候 说明这个队列是有空闲空间可以用来存储的 但是已经存不进去 

如果这个时候 要插入新的数据 就会出现队满插不进去的现象 这种现象就可以叫“假溢出”

 4.应用2:优先级队列

优先级队列是由一组数据组成的数据集合 给每个元素分配一个数字来标记它的优先级 数字越小 优先级越高

优先级队列不同于队列的地方是 每次出队的是队中优先级最高的元素

如果两个元素的优先级相同 那么就按照先进先出的规则进行操作

二.代码实现

1.队列的操作:①Init ②Push ③Pop ④IsEmpty

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 
 4 typedef struct node
 5 {
 6     int num;
 7     struct node* pNext;
 8 }MyQueue;
 9 
10 typedef struct node2
11 {
12     int count;
13     MyQueue* pHead;
14     MyQueue* pTail;
15 }Queue;
16 
17 void q_Init(Queue** pQueue)
18 {
19     *pQueue = (Queue*)malloc(sizeof(Queue));
20     (*pQueue) -> count = 0;
21     (*pQueue) -> pHead = NULL;
22     (*pQueue) -> pTail = NULL;
23 }
24 
25 void q_Push(Queue* pQueue,int n)
26 {
27     if(pQueue == NULL) return ;
28 
29     MyQueue* pMyQueue = (MyQueue*)malloc(sizeof(Queue));
30     pMyQueue -> num = n;
31     pMyQueue -> pNext = NULL;
32 
33     if(pQueue -> pHead == NULL)
34     {
35         pQueue -> pHead = pMyQueue;
36         pQueue -> pTail = pMyQueue;
37     }
38     else
39     {
40         pQueue -> pTail -> pNext = pMyQueue;
41         pQueue -> pTail = pMyQueue;
42     }
43 
44     pQueue -> count ++;
45 }
46 
47 int q_Pop(Queue* pQueue)
48 {
49     if(pQueue == NULL || pQueue -> count == 0) return -1;
50 
51     MyQueue* pDel = pQueue -> pHead;
52     int n = pDel -> num;
53     pQueue -> pHead = pQueue -> pHead -> pNext;
54 
55     if(pQueue -> pHead == pQueue -> pTail)
56     {
57         pQueue -> pTail = NULL;
58     }
59 
60     free(pDel);
61     pDel = NULL;
62 
63     pQueue -> count --;
64     return n;
65 }
66 
67 int q_IsEmpty(Queue* pQueue)
68 {
69     return pQueue -> count == 0? 1:0;
70 }
71 
72 int main()
73 {
74     Queue* pQueue;
75     q_Init(&pQueue);
76     q_Push(pQueue,11);
77     q_Push(pQueue,12);
78     q_Push(pQueue,13);
79 
80     printf("%d\n",q_Pop(pQueue));
81     printf("%d\n",q_Pop(pQueue));
82     printf("%d\n",q_Pop(pQueue));
83     printf("%d\n",q_Pop(pQueue));
84     return 0;
85 }

2.用两个栈实现队列的功能

①思想:定义一个新的队列的结构体 里面放两个栈的指针

在进行入队操作时 首先检查栈2中是否还有元素没有放回栈1 如果栈2中还有元素 逐个放回

如果没有 把想要入队的元素直接插入到栈1中即可

在进行出队操作时 应该先检查栈1中是否还有元素没有放回到栈2中 如果栈1中还有元素 逐个放回

如果没有 在栈2中取走想要得到的元素的值即可

②代码:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 typedef struct node
  5 {
  6     int num;
  7     struct node * pNext;
  8 }MyStack;
  9 
 10 typedef struct node2
 11 {
 12     int count;
 13     MyStack* pTop;
 14 }Stack;
 15 
 16 typedef struct node3
 17 {    
 18     int count;
 19     Stack* pStack1;
 20     Stack* pStack2;
 21 }Queue;
 22 
 23 void s_Init(Stack** ppStack)
 24 {
 25     (*ppStack) = (Stack*)malloc(sizeof(Stack));
 26     (*ppStack) -> count = 0;
 27     (*ppStack) -> pTop = NULL;
 28 }
 29 
 30 void s_Push(Stack* pStack,int n)
 31 {
 32     if(pStack == NULL) return ;
 33     
 34     MyStack* pMyStack = (MyStack*)malloc(sizeof(MyStack));
 35     pMyStack -> num = n;
 36     pMyStack -> pNext = pStack -> pTop;
 37     pStack -> pTop = pMyStack;
 38 
 39     pStack -> count ++;
 40 }
 41 
 42 int s_Pop(Stack* pStack)
 43 {
 44     if(pStack == NULL || pStack -> count == 0) return -1;
 45     
 46     MyStack* pDel = pStack -> pTop;
 47     int n = pDel -> num;
 48     pStack -> pTop = pStack -> pTop -> pNext;
 49     free(pDel);
 50     pDel = NULL;
 51 
 52     pStack -> count --;
 53     return n;
 54 }
 55 
 56 void q_Init(Queue** pQueue)
 57 {
 58     *pQueue = (Queue*)malloc(sizeof(Queue));
 59     (*pQueue) -> count = 0;
 60     (*pQueue) -> pStack1 = NULL;
 61     (*pQueue) -> pStack2 = NULL;
 62 
 63     s_Init(&((*pQueue) -> pStack1));
 64     s_Init(&((*pQueue) -> pStack2));
 65 }
 66 
 67 void q_Push(Queue* pQueue,int n)
 68 {
 69     if(pQueue == NULL) return ;
 70 
 71     while(pQueue -> pStack2 -> count != 0)
 72     {
 73         s_Push(pQueue -> pStack1,s_Pop(pQueue -> pStack2));
 74     }
 75 
 76     s_Push(pQueue -> pStack1,n);
 77     pQueue -> count ++;
 78 }
 79 
 80 int q_Pop(Queue* pQueue)
 81 {
 82     if(pQueue -> pStack1 == NULL) return -1; 
 83     while(pQueue -> pStack1 -> count != 0)
 84     {
 85         int n = s_Pop(pQueue -> pStack1);
 86         s_Push(pQueue -> pStack2,n);
 87     }
 88 
 89     int n = s_Pop(pQueue -> pStack2);
 90     while(pQueue -> pStack2 -> count != 0)
 91     {
 92         int n = s_Pop(pQueue -> pStack2);
 93         s_Push(pQueue -> pStack1,n);
 94     }
 95     pQueue -> count --;
 96     return n;
 97 }
 98 
 99 int main()
100 {
101     Queue* pQueue = NULL;
102     q_Init(&pQueue);
103     q_Push(pQueue,10);
104     q_Push(pQueue,11);
105     q_Push(pQueue,12);
106     printf("%d\n",q_Pop(pQueue));
107     printf("%d\n",q_Pop(pQueue));
108     printf("%d\n",q_Pop(pQueue));
109     printf("%d\n",q_Pop(pQueue));
110     printf("%d\n",q_Pop(pQueue));
111     
112     return 0;
113 }

3.用两个队列实现栈的功能

①思想:定义一个新的栈的结构体 里面有两个队列的指针

当进行入栈操作的时候 如果两个队列都是空的 放在哪个队列里面都可以

如果有一个是非空的 那么就放在这个非空的队列里 入栈成功

当进行出栈操作的时候 假设元素都在队列1中(在队列2中同理)

先把队列1中的元素依次出队 直到队列1中的元素只剩下一个 那么队列1中剩下的这个元素就是要出栈的元素

把这个元素出队列 即出栈成功

②代码:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 typedef struct node
  5 {
  6     int num;
  7     struct node* pNext;
  8 }MyQueue;
  9 
 10 typedef struct node2
 11 {
 12     int count;
 13      MyQueue* pHead;
 14     MyQueue* pTail;
 15 }Queue;
 16 
 17 typedef struct node3
 18 {
 19     int count;
 20     Queue* pQueue1;
 21     Queue* pQueue2;
 22 }Stack;
 23 
 24 void q_Init(Queue** pQueue)
 25 {
 26     *pQueue = (Queue*)malloc(sizeof(Queue));
 27     (*pQueue) -> count = 0;
 28     (*pQueue) -> pHead = NULL;
 29     (*pQueue) -> pTail = NULL;
 30 }
 31 
 32 void s_Init(Stack** pStack)
 33 {
 34     *pStack = (Stack*)malloc(sizeof(Stack));
 35     (*pStack) -> count = 0;
 36     (*pStack) -> pQueue1 = NULL;
 37     (*pStack) -> pQueue2 = NULL;
 38 
 39     q_Init(&((*pStack) -> pQueue1));
 40     q_Init(&((*pStack) -> pQueue2)); 
 41 }
 42 
 43 void q_Push(Queue* pQueue,int n)
 44 {
 45     if(pQueue == NULL) return ;
 46     
 47     MyQueue* pMyQueue = (MyQueue*)malloc(sizeof(Queue));
 48     pMyQueue -> num = n;
 49     pMyQueue -> pNext = NULL;
 50 
 51     if(pQueue -> pHead == NULL)
 52     {
 53         pQueue -> pHead = pMyQueue;
 54         pQueue -> pTail = pMyQueue;
 55     }
 56     else
 57     {
 58         pQueue -> pTail -> pNext = pMyQueue;
 59         pQueue -> pTail = pMyQueue;
 60     }
 61     
 62     pQueue -> count ++;
 63 }
 64 
 65 int q_Pop(Queue* pQueue)
 66 {
 67     if(pQueue == NULL || pQueue -> count == 0) return -1;
 68     
 69     MyQueue* pDel = pQueue -> pHead;
 70     int n = pDel -> num;
 71     pQueue -> pHead = pQueue -> pHead -> pNext;
 72     
 73     if(pQueue -> pHead == pQueue -> pTail)
 74     {
 75         pQueue -> pTail = NULL;
 76     }
 77 
 78     free(pDel);
 79     pDel = NULL;
 80     
 81     pQueue -> count --;
 82     return n;
 83 }
 84 
 85 int q_IsEmpty(Queue* pQueue)
 86 {
 87     return pQueue -> count == 0? 1:0;
 88 }
 89 
 90 void s_Push(Stack* pStack,int n)
 91 {
 92     if(pStack == NULL || pStack -> pQueue1 == NULL || pStack -> pQueue2 == NULL) return;
 93     
 94     if(!q_IsEmpty(pStack -> pQueue1))
 95     {
 96         q_Push(pStack -> pQueue1,n);
 97     }
 98     else
 99     {
100         q_Push(pStack -> pQueue2,n);
101     }
102 
103     pStack -> count ++;
104 }
105 
106 int s_Pop(Stack* pStack)
107 {
108     if(pStack == NULL || pStack -> pQueue1 == NULL || pStack -> pQueue2 == NULL || pStack -> count == 0) return -1;
109     
110     int n;
111     if(!q_IsEmpty(pStack -> pQueue2))
112     {
113         while(pStack -> pQueue2 -> count > 1)
114         {
115             q_Push(pStack -> pQueue1,q_Pop(pStack -> pQueue2));
116         }
117         n = q_Pop(pStack -> pQueue2);
118     }    
119     else
120     {
121         while(pStack -> pQueue1 -> count > 1)
122         {
123             q_Push(pStack -> pQueue2,q_Pop(pStack -> pQueue1));
124         }
125         n = q_Pop(pStack -> pQueue1);
126     }
127     
128     pStack -> count --;
129     return n;
130 }
131 
132 int main()
133 {
134     Stack* pStack;
135     s_Init(&pStack);
136     s_Push(pStack,11);
137      s_Push(pStack,12);
138     s_Push(pStack,13);
139 
140     printf("%d\n",s_Pop(pStack));
141     printf("%d\n",s_Pop(pStack));
142     printf("%d\n",s_Pop(pStack));
143     printf("%d\n",s_Pop(pStack));
144     return 0;
145 }

 

posted @ 2018-10-17 15:07  Aaaaaalei  阅读(218)  评论(0编辑  收藏  举报