数据结构第十周作业(1)——链队列&循环队列

先认识一下队列,它可以看作是平常排队,先进先出

一.链队列

1.代码

#include <stdio.h>
#include <malloc.h>

/*
  创建节点
 */
typedef struct LinkNode {
    int data;
    struct LinkNode* next;
}*LinkNodePtr;

/*
  队列结构
 */
typedef struct LinkQueue {
    LinkNodePtr front;//头指针
    LinkNodePtr rear;//尾指针
}*LinkQueuePtr;

/*
  初始化
 */
LinkQueuePtr initQueue() {
    LinkQueuePtr resultPtr = (LinkQueuePtr)malloc(sizeof(struct LinkQueue));
    LinkNodePtr headerPtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
    headerPtr->next = NULL;//创建头节点
  
    resultPtr->front = headerPtr;
    resultPtr->rear = headerPtr;
    return resultPtr;
}

/*
  输出队列
 */
void outputLinkQueue (LinkQueuePtr paraQueuePtr) {
    LinkNodePtr tempPtr = paraQueuePtr->front->next;
    while (tempPtr != NULL) {
        printf("%d ", tempPtr->data);
        tempPtr = tempPtr->next;
    }//of while
    printf("\r\n");
}

/*
  入队
 */
void enqueue (LinkQueuePtr paraQueuePtr, int paraElement) {
    //创建一个新节点
    LinkNodePtr tempNodePtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
    tempNodePtr->data = paraElement;
    tempNodePtr->next = NULL;

    //连接新节点
    paraQueuePtr->rear->next = tempNodePtr;
 
    //rear移动到新的尾节点
    paraQueuePtr->rear = tempNodePtr;
}

/*
  出队
 */
int dequeue (LinkQueuePtr paraQueuePtr) {
    int resultValue;
    LinkNodePtr tempNodePtr;

    //判断队列是否为空
    if (paraQueuePtr->front == paraQueuePtr->rear) {
        printf("The queue is empty.\r\n");
        return -1;
    }//of if
 
    //往后移动头指针
    tempNodePtr = paraQueuePtr->front->next;
    resultValue = tempNodePtr->data;
    paraQueuePtr->front->next = paraQueuePtr->front->next->next;

    //队列是否只剩一个元素
    if (paraQueuePtr->rear == tempNodePtr) { 
         paraQueuePtr->rear = paraQueuePtr->front;
    }//of if

    //释放出队节点的空间
    tempNodePtr = NULL;

    return resultValue;
}

void testLinkQueue() {
    LinkQueuePtr tempQueuePtr;
    tempQueuePtr = initQueue();
    enqueue(tempQueuePtr, 10);
    enqueue(tempQueuePtr, 30);
    enqueue(tempQueuePtr, 50);

    outputLinkQueue(tempQueuePtr);

    printf("dequeue gets %d\r\n", dequeue(tempQueuePtr));
    printf("dequeue gets %d\r\n", dequeue(tempQueuePtr));
    printf("dequeue gets %d\r\n", dequeue(tempQueuePtr));
    printf("dequeue gets %d\r\n", dequeue(tempQueuePtr));

    enqueue(tempQueuePtr, 8);
    outputLinkQueue(tempQueuePtr);
}

int main() {
    testLinkQueue();
    return 1;
}

2.运行结果

3.图示

4.心得体会

①.链队列中多创建一个尾指针是避免遍历时额外花费时间,增加时间复杂度;

②.注意出队时需要释放节点;

③.与链表结构不同的是,增加了头指针和尾指针,用于入队和出队等操作。

二.循环队列

1.代码

#include <stdio.h>
#include <malloc.h>

#define TOTAL_SPACE 5

/* 
  创建队列结构
 */
typedef struct CircleIntQueue {
    int data[TOTAL_SPACE];

    int front;//头部

    int rear;//尾部
}*CircleIntQueuePtr;

/*
  初始化
 */
CircleIntQueuePtr initQueue() {
    CircleIntQueuePtr resultPtr = (CircleIntQueuePtr)malloc(sizeof(struct CircleIntQueue));
    resultPtr->front = 0;
    resultPtr->rear = 0;

    return resultPtr;
}

/* 
  入队
 */
void enqueue(CircleIntQueuePtr paraPtr, int paraValue) {
    printf("Enqueue: %d ", paraValue);
    //判断队列是否满了
    if ((paraPtr->rear + 1) % TOTAL_SPACE == paraPtr->front) {
        printf("Queue full.\r\n");
        return;
    }//of if

    paraPtr->data[paraPtr->rear] = paraValue;
    paraPtr->rear = (paraPtr->rear + 1) % TOTAL_SPACE;
}

/*
  出队
 */
int dequeue(CircleIntQueuePtr paraPtr) {
    int resultValue;
    //判断队列是否为空
    if (paraPtr->front == paraPtr->rear) {
        printf("No element in the queue.\r\n");
        return -1;
    }//of if
 
    resultValue = paraPtr->data[paraPtr->front];
    paraPtr->front = (paraPtr->front + 1) % TOTAL_SPACE;

    return resultValue;
}

/*
  打印队列
 */
void outputCircleIntQueue(CircleIntQueuePtr paraPtr) {
    int i;
    //判断队列为空
    if (paraPtr->front == paraPtr->rear) {
        printf("Empty queue.");
        return;
    }//of if

    printf("Element in the queue: ");
    for (i = paraPtr->front; i != paraPtr->rear; i = (i + 1) % TOTAL_SPACE) {
        printf("data[%d] = %d, ", i, paraPtr->data[i]);
    }//of for
  
    printf("\r\n");
}

void testCircleIntQueue() {
    int i = 10;
    CircleIntQueuePtr tempPtr = initQueue();
    for (; i < 16; i ++) {
        enqueue(tempPtr, i);
    }//of for

    outputCircleIntQueue(tempPtr);

    for (i = 0; i < 6; i ++) {
         printf("dequeue gets %d\r\n", dequeue(tempPtr));
    }//of for

    for (i = 3; i < 6; i ++) {
         enqueue(tempPtr, i);
    };

    for (i = 20; i < 30; i ++) {
        enqueue(tempPtr, i);
        printf("dequeue gets %d\r\n", dequeue(tempPtr));
        outputCircleIntQueue(tempPtr);
    }//of for
}

int main() {
    testCircleIntQueue();
    return 1;
}

2.运行结果

3.图示

4.心得体会

①.循环队列好处是当出队时,前面空出来的位置仍可被使用,直到队列已满;

②.此处是rear尾部是指向最后一个元素,是

如果是指向最后一个元素的后一位,则两个代码位置调换

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值