622.设计循环队列

在这里插入图片描述
在这里插入图片描述

typedef struct {
    int* a;
    int head;
    int tail;
    int k;
} MyCircularQueue;

bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);



//初始化
MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));

    obj->a=(int*)malloc(sizeof(int)*(k+1));
    obj->head=0;
    obj->tail=0;
    obj->k=k;

    return obj;
}
//放入数据
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
        return false;

    obj->a[obj->tail]=value;
    obj->tail++;
    (obj->tail)%=(obj->k+1);
    return true;
}
//删前面的数据置空
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
        return false;

    ++obj->head;

    obj->head%=(obj->k+1);
    return true;
}
//取头
int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
        return -1;
    else
        return obj->a[obj->head];
}
//取尾
int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
        return -1;
    else
        return obj->a[(obj->tail+obj->k)%(obj->k+1)];

}
//判空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->head==obj->tail;
}
//判满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->tail+1)%(obj->k+1)==obj->head;
}
//释放
void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->a);
    free(obj);
}

/**
 * Your MyCircularQueue struct will be instantiated and called as such:
 * MyCircularQueue* obj = myCircularQueueCreate(k);
 * bool param_1 = myCircularQueueEnQueue(obj, value);
 
 * bool param_2 = myCircularQueueDeQueue(obj);
 
 * int param_3 = myCircularQueueFront(obj);
 
 * int param_4 = myCircularQueueRear(obj);
 
 * bool param_5 = myCircularQueueIsEmpty(obj);
 
 * bool param_6 = myCircularQueueIsFull(obj);
 
 * myCircularQueueFree(obj);
*/

循环队列就是在有限空间保证先进先出,重复使用
在这里插入图片描述
我们在这里定义两个指针,一个队头指针head和一个队尾指针tail都指向队头。当放入数据时(push),tail指针++并且指向放入元素的下一个位置。当删去数据时(pop),直接移动head让head++就删去了。但是这里有一个问题,一开始head=tail为空当随着往下进行的时候,head=tail为满。

所以我们这里多开一个空间,开k+1个空间但是只放进k个元素。

在这里插入图片描述
创建一个结构体把,头指针和尾指针还有整个数组以及元素个数管理起来。

在这里插入图片描述
开k+1个空间,但是只放进k个元素。

在这里插入图片描述
在这里插入图片描述

判空:当在这种情况下时,head和tail相等时只会是在为空的时候。所以判空时,只需判断head是否等于tail。
判满:结合上图,当元素放满时,tail的下一个位置就是head,根据取模得到关系(tail+1)%(k+1)==head
在这里插入图片描述
先判断是否为满,在tail指针处放入值然后让tail++往后走。因为是循环队列要注意tail到最后时要形成循环队列,所以tail指针要返回去。
在这里插入图片描述
头指针往后走删除数据,走到最后也要返回去。
在这里插入图片描述
取头:如果为空就返回-1,否则返回头指针的节点。
取尾:这里还有另外一种写法,如果tail为0也就是放满了tail又循环回来了,此时取下标为k位置的数。如果是正常情况就取tail-1。在这里插入图片描述

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
好的,我会逐一回答你的问题。 1. 旅游路线图的邻接表存储可以用C语言中的结构体来实现。定义一个结构体表示每个顶点,包含一个顶点名称和一个指向邻接点链表的指针。邻接点链表中每个节点包含一个邻接点的名称和一个指向下一个邻接点的指针。可以这样实现: ``` typedef struct vertex { char name; struct edge *edge_list; } Vertex; typedef struct edge { char name; struct edge *next; } Edge; ``` 然后编写一个函数,让用户输入这张图,用邻接表存储。可以先输入顶点数量,然后逐个输入每个顶点及其邻接点。 2. 深度优先搜索遍历可以用递归实现。从任意一个顶点开始,先访问该顶点,然后递归访问它的邻接点,直到所有可达的顶点都被访问过。可以这样实现: ``` void dfs(Vertex *vertex, int *visited) { visited[vertex->name - 'a'] = 1; printf("%c ", vertex->name); Edge *edge = vertex->edge_list; while (edge != NULL) { if (!visited[edge->name - 'a']) { dfs(&graph[edge->name - 'a'], visited); } edge = edge->next; } } ``` 其中visited数组用来记录每个顶点是否被访问过。 3. 循环队列的初始化可以用一个数组和两个指针来实现。定义一个结构体表示队列,包含一个数组和两个指针,分别表示队头和队尾。入队操作将元素插入队尾,出队操作从队头取出元素。需要注意的是,队列满时需要循环利用数组空间,即从队头位置重新插入元素。 ``` typedef struct queue { int data[MAX_SIZE]; int front, rear; } Queue; void init_queue(Queue *q) { q->front = q->rear = 0; } int is_empty(Queue *q) { return q->front == q->rear; } int is_full(Queue *q) { return (q->rear + 1) % MAX_SIZE == q->front; } void enqueue(Queue *q, int value) { if (is_full(q)) { printf("Queue is full.\n"); return; } q->data[q->rear] = value; q->rear = (q->rear + 1) % MAX_SIZE; } int dequeue(Queue *q) { if (is_empty(q)) { printf("Queue is empty.\n"); return -1; } int value = q->data[q->front]; q->front = (q->front + 1) % MAX_SIZE; return value; } ``` 4. 利用循环队列对图实现广度优先搜索遍历。从任意一个顶点开始,先访问该顶点,然后将其邻接点入队,依次取出队头元素并访问其邻接点,直到队列为空。可以这样实现: ``` void bfs(Vertex *vertex, int *visited) { Queue q; init_queue(&q); visited[vertex->name - 'a'] = 1; enqueue(&q, vertex->name - 'a'); while (!is_empty(&q)) { int v = dequeue(&q); printf("%c ", v + 'a'); Edge *edge = graph[v].edge_list; while (edge != NULL) { if (!visited[edge->name - 'a']) { visited[edge->name - 'a'] = 1; enqueue(&q, edge->name - 'a'); } edge = edge->next; } } } ``` 其中visited数组用来记录每个顶点是否被访问过。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值