zoukankan      html  css  js  c++  java
  • 队列的链式存储结构(C语言实现)

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 #define OK 1
      5 #define ERR 2
      6 #define TRUE 1
      7 #define FALSE 0
      8 
      9 typedef int status; //定义函数返回的状态,OK & ERR
     10 typedef char datatype; //定义队列中每个元素的数据类型,这里暂定为字符型
     11 
     12 typedef struct LinkQueue_anon{
     13     datatype data; //数据区
     14     struct LinkQueue_anon * next; //指针区
     15 } LinkQueue;
     16 typedef struct {
     17     LinkQueue * front, * rear;
     18     /*
     19     创建队列的游标,保存着队列的头尾指针所指向的结点
     20     front指向队列的第一个结点(队头),rear指向队列的最后一个结点(队尾)
     21     规定:
     22         当front=rear=NULL时,表示队列为空
     23         当front=rear!=NULL时,表示队列只有一个元素
     24     */
     25 }LinkQueueCursor;
     26 
     27 /* 函数原型,队列的基本操作,与栈相同 */
     28 LinkQueueCursor *createLinkQueue(datatype first_node_value);
     29 status isEmpty(LinkQueueCursor *L);
     30 void clear(LinkQueueCursor *L);
     31 datatype getTop(LinkQueueCursor *L);
     32 int getLength(LinkQueueCursor *L);
     33 status push(LinkQueueCursor *L, datatype node_to_push);
     34 datatype pop(LinkQueueCursor *L);
     35 void showQueue(LinkQueueCursor *L);
     36 
     37 int main(){
     38     /* 测试 */
     39     LinkQueueCursor * mycursor;
     40     mycursor=createLinkQueue('1'); //创建一个游标,同时入队一个元素,其值为'1'
     41     printf("isEmpty = %d
    ",isEmpty(mycursor));
     42     printf("Length = %d
    ",getLength(mycursor));
     43     push(mycursor,'a');
     44     push(mycursor,'b');
     45     push(mycursor,'c');
     46     push(mycursor,'d');
     47     printf("isEmpty = %d
    ",isEmpty(mycursor));
     48     printf("Length = %d
    ",getLength(mycursor));
     49     showQueue(mycursor);
     50     putchar('
    ');
     51     printf("pop = %c
    ",pop(mycursor));
     52     printf("pop = %c
    ",pop(mycursor));
     53     printf("getTop = %c
    ",getTop(mycursor));
     54     printf("isEmpty = %d
    ",isEmpty(mycursor));
     55     printf("Length = %d
    ",getLength(mycursor));
     56     showQueue(mycursor);
     57     putchar('
    ');
     58     clear(mycursor);
     59     printf("isEmpty = %d
    ",isEmpty(mycursor));
     60     printf("Length = %d
    ",getLength(mycursor));
     61 
     62     return 0;
     63 }
     64 
     65 LinkQueueCursor *createLinkQueue(datatype first_node_value){
     66     LinkQueueCursor *tmp_cur;
     67     LinkQueue *tmp;
     68     tmp_cur=malloc(sizeof(LinkQueueCursor)); //void*类型指针能自动转为其他类型的指针
     69     tmp=malloc(sizeof(LinkQueue));
     70     tmp_cur->front=tmp_cur->rear=tmp; //初始化游标
     71     tmp->data=first_node_value; //初始化数据区
     72     tmp->next=NULL; //初始化指针区
     73     return tmp_cur;
     74 }
     75 status isEmpty(LinkQueueCursor *L){
     76     if (L->front==L->rear && L->front==NULL)
     77         return TRUE;
     78     else
     79         return FALSE;
     80 }
     81 void clear(LinkQueueCursor *L){
     82     LinkQueue * p,* q;
     83     if (isEmpty(L)) return; //空队列,不需要clear,所以直接返回
     84     if (L->front==L->rear && L->front!=NULL){ //只有一个元素的队列,front和rear都指向这个元素
     85         free(L->front);
     86         L->front=L->rear=NULL; //把队列设为空
     87         return;
     88     }
     89     /* 当队列的元素大于1时 */
     90     p=L->front; //p指向当前要被删除的结点
     91     while (p){
     92         //当p不为NULL继续循环
     93         q=p->next; //q指向p的下一个结点
     94         free(p);
     95         p=q; //交换
     96     }
     97     L->front=L->rear=NULL; //把队列设为空
     98 
     99 }
    100 datatype getTop(LinkQueueCursor *L){
    101     return L->front->data; //直接返回队头的数据即可
    102 }
    103 int getLength(LinkQueueCursor *L){
    104     int i=0;
    105     LinkQueue * p;
    106     if (isEmpty(L)) return 0; //空队列,返回0
    107     if (L->front==L->rear && L->front!=NULL) return 1; //规定:front=rear,说明队列只有一个元素
    108     /* 队列的长度大于1时 */
    109     p=L->front;
    110     while (p!=L->rear){ //还没到rear(队尾)则继续循环
    111         i++; p=p->next;
    112     }
    113     return i+1;
    114     /*
    115     上面的【队列的长度大于1时】还能用下面的等价代码代替
    116     p=L->front;
    117     while (p){ //p不为NULL则继续循环,因为rear(队尾)结点的next(指针区)一定是NULL
    118         i++; p=p->next;
    119     }
    120     return i;
    121     */
    122 }
    123 status push(LinkQueueCursor *L, datatype node_to_push){
    124     //node_to_insert表示想要在队尾处入队的元素
    125     LinkQueue * s=malloc(sizeof(LinkQueue));
    126     s->data=node_to_push; //初始化新入队的元素
    127     s->next=NULL;
    128     if (isEmpty(L)==TRUE){
    129         //插入到空队列
    130         L->front=L->rear=s; //入队,当队列只有一个元素时,规定front和rear都指向这个元素
    131     }else{
    132         //插入到已存在元素的队列
    133         L->rear->next=s; //入队,将新元素附在rear指向的结点的后面
    134         L->rear=s; //rear后移,即将它指向新元素
    135     }
    136     return OK;
    137 }
    138 datatype pop(LinkQueueCursor *L){
    139     //出队,即将队头删除
    140     datatype v;
    141     LinkQueue * s;
    142     if (isEmpty(L)) return (datatype)ERR; //空队列
    143     if (L->front==L->rear && L->front!=NULL){ //队列只有一个元素
    144         v=L->front->data; //把这个元素的值赋值给临时变量
    145         free(L->front); //删除这个元素
    146         L->front=L->rear=NULL; //把队列设置为空
    147     }else{
    148         v=L->front->data; //将要删除的元素的值先赋值给临时变量
    149         s=L->front; //将要删除的元素先赋值给临时变量
    150         L->front=L->front->next; //将游标所保存的front后移到下个结点(元素)
    151         free(s); //删除原来的头结点(元素)
    152     }
    153     return v; //返回出队结点(元素)的值
    154 }
    155 void showQueue(LinkQueueCursor *L){
    156     int i;
    157     int total=getLength(L);
    158     LinkQueue * p;
    159     p=L->front;
    160     for (i=0; i<total; i++){
    161         printf("%c	",p->data); p=p->next;
    162     }
    163 }
    164 /*
    165     队列的定义:只允许在一端进行插入,另一端进行删除的线性表,也是一种操作受限的线性表
    166     一般,把允许插入的一端叫做队尾,允许删除的一端叫做队头
    167     不含任何元素的队列就是空队
    168     所以,队列又称先进先出(First in First out)的线性表
    169     队列的链式存储其实就是线性表中的单链表,只不过它只能尾进头出
    170 */
    171 /* 环境: Code::Blocks with GCC 5.1 */

    运行截图:

  • 相关阅读:
    (Vue中)cehart在同一个dom上画图图切换时饼图有折线图的坐标系
    linux(centos7)修改服务器时间
    centos6 yum源不能使用
    Linux 使用 history 来减少重复命令的几个实用技巧。
    7个Shell 拿来就用脚本实例!
    keepalived的配置解析&安装与爬坑
    linux最全命令使用手册
    linux各种误删文件恢复方法(经典强推)
    位运算符
    SQL 书写、执行顺序
  • 原文地址:https://www.cnblogs.com/ryzz/p/12232423.html
Copyright © 2011-2022 走看看