• <数据结构> 队列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
    ",q_Pop(pQueue));
    81     printf("%d
    ",q_Pop(pQueue));
    82     printf("%d
    ",q_Pop(pQueue));
    83     printf("%d
    ",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
    ",q_Pop(pQueue));
    107     printf("%d
    ",q_Pop(pQueue));
    108     printf("%d
    ",q_Pop(pQueue));
    109     printf("%d
    ",q_Pop(pQueue));
    110     printf("%d
    ",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
    ",s_Pop(pStack));
    141     printf("%d
    ",s_Pop(pStack));
    142     printf("%d
    ",s_Pop(pStack));
    143     printf("%d
    ",s_Pop(pStack));
    144     return 0;
    145 }
  • 相关阅读:
    JDK源码分析之hashmap就这么简单理解
    JVM笔记11-类加载器和OSGI
    JVM笔记10-性能优化之高级特性
    Java并发编程笔记之ThreadLocal内存泄漏探究
    Java并发编程笔记之FutureTask源码分析
    Java并发编程笔记之SimpleDateFormat源码分析
    Java并发编程笔记之Timer源码分析
    Java并发编程笔记之Semaphore信号量源码分析
    Java并发编程笔记之CyclicBarrier源码分析
    Java并发编程笔记之 CountDownLatch闭锁的源码分析
  • 原文地址:https://www.cnblogs.com/Aaaaaalei0612/p/9767000.html
Copyright © 2020-2023  润新知