• 数据结构学习5——队列


    队列:先进先出的线性表,它只允许在一端(队尾)进行插入操作,在另一端(队首)进行删除操作。与栈的插入和删除都在栈顶进行不同。

    这里只说队列的链式存储。国际惯例,先上源码

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<malloc.h>
      4 
      5 //定义队列
      6 typedef struct node{
      7     int data;
      8     struct node *next;
      9 }Queue;
     10 //定义对手指针和队尾指针
     11 typedef struct pointer{
     12     Queue *front;//队首指针,对手指针不存放队列元素
     13     Queue *rear;//队尾指针,存放队尾的数据元素
     14 }Qpointer;
     15 
     16 //队列初始化
     17 void QueueInit(Qpointer *qp)
     18 {
     19     Queue *que;
     20     que=(Queue*)malloc(sizeof(Queue));
     21     que->next=NULL;
     22     //队首和队尾指向同一个内存空间,指针域为NULL
     23     qp->front=que;
     24     qp->rear=que;
     25 }
     26 
     27 //判断队列是否为空:为空返回1,不为空返回0
     28 int IsEmpty(Qpointer *qp)
     29 {
     30     //判断方法:对手指针和队尾指针是否相同
     31     if(qp->front==qp->rear)
     32     {
     33         return 1;
     34     }
     35     return 0;
     36 }
     37 
     38 //插入数据元素:插入成功返回1,失败返回0
     39 int QueuePush(Qpointer *qp,int element)
     40 {
     41     Queue *que;
     42     que=(Queue*)malloc(sizeof(Queue));
     43     if(que==NULL)
     44     {
     45         return 0;
     46     }
     47     que->data=element;
     48     que->next=NULL;
     49     qp->rear->next=que;//将节点插入队列尾
     50     qp->rear=que;//调整队尾指针
     51     return 0;
     52 }
     53 
     54 //删除数据元素:删除成功返回1,失败返回0
     55 int QueuePop(Qpointer *qp,int *element)
     56 {
     57     Queue *que;
     58     if(IsEmpty(qp))
     59     {
     60         return 0;
     61     }
     62     que=qp->front->next;//que指向队列头结点的下一个节点,即真正的队首
     63     *element=que->data;//将要出队列的元素
     64     qp->front->next=que->next;
     65     //判断队列是否就只剩下一个元素
     66     if(qp->rear==que)
     67     {
     68         qp->rear=qp->front;
     69     }
     70     free(que);
     71     return 1;
     72 }
     73 
     74 int main()
     75 {
     76     Qpointer *qp;
     77     int x;
     78     //初始化队列
     79     qp=(Qpointer*)malloc(sizeof(Qpointer));
     80     QueueInit(qp);
     81     printf("input positive integers:\n");
     82     scanf("%d",&x);
     83     while(x>0)
     84     {
     85         QueuePush(qp,x);
     86         scanf("%d",&x);
     87     }
     88     //输出队列:队首->队尾
     89     Queue *p=qp->front->next;
     90     if(p==NULL)
     91         return 0;
     92     printf("queue element:\n");
     93     while(p)
     94     {
     95         printf("%d ",p->data);
     96         p=p->next;
     97     }
     98     printf("\n");
     99     //删除队列
    100     printf("delete queue:\n");
    101     while(QueuePop(qp,&x))
    102     {
    103         printf("%d ",x);
    104     }
    105     printf("\n");
    106     //释放内存空间
    107     p=qp->front;
    108     free(p);
    109     free(qp);
    110 
    111     return 0;
    112 }

    1.队列定义:这里除了定义队列中节点的数据结构,还专门定义了队首和队尾,方便对队列操作,这样一来,队列的操作就只需要对pointer结构体中的对手指真和队尾指针进行。

    2.判断是否为空
    当队首指针和队尾指针只想同一块地址时,队列为空,队列为空就是说队列中没有数据元素。注意队首front只是队列的头结点,并不代表队列的实际队首,在队列不为空时,队列的实际队首应该是头结点的下一个节点。

    3.插入数据元素

    插入在队尾进行,插入后,新插入的节点就成为了队尾。

    4.删除数据元素

    删除在队首进行,需要注意的是,当实际的队首也是队尾时,删除队列中的一个数据后队列就成为了空队列(rear=front)。最后不要忘了将删除的数据的内存空间释放掉。

    5.注意点

    最后释放内存时,一定要先释放掉pointer中的队首指针和队尾指针指向的内存空间,再释放掉pointer结构体指向的内存空间。

    使用GDB调试,可知pointer结构体的内存模型如下:

    这时初始化队列后的情况,并未插入任何数据。pointer结构体指针变量qp指向0x804b008,因为qp中有两个指针变量,所以占8个字节的内存空间,分别存放front(指向0x804b018)指针变量和rear(指向0x804b018)指针变量

  • 相关阅读:
    Leetcode 剑指 Offer 27(二叉树的镜像)
    Leetcode 1022从根到叶的二进制之和
    Leetcode 993二叉树的堂兄弟节点
    Leetcode 965单值二叉树
    Leetcode 938 二叉搜索树的范围和
    hdu 2082 找单词
    母函数模板
    hdu 1398 Square Coins
    hdu 1085 Holding Bin-Laden Captive!
    hdu 1028 Ignatius and the Princess III
  • 原文地址:https://www.cnblogs.com/Romi/p/2660954.html
Copyright © 2020-2023  润新知