队列的数据结构实验报告

  • 实验目的:

1、理解队列数据结构的概念和特点。

2、熟悉队列的应用场景和算法实现。

二、实验内容(实验题目与说明)

实现了一个循环队列,具有功能:

  1. 初始化队列。
  2. 判断队列是否为空。
  3. 判断队列是否已满。
  4. 入队。
  5. 出队。

在 main() 函数中,先初始化队列,然后依次将元素 'a'、'b'、'c' 入队,再出队一个元素,输出该元素,接着将元素 'd'、'e'依次入队,最后输出出队序列,即元素 'b'、'c'、'd'、'e'。

三、算法设计(核心代码或全部代码)

#include <stdio.h>

#include <stdlib.h>

#define max 10

typedef struct {

    char data[max];

    int front;

    int rear;

} Queue;

// 初始化

void initQueue(Queue* q) {

    q->front = q->rear = 0;

}

// 判断队列是否非空

int Empty(const Queue* q) {

    return q->front == q->rear;

}

// 判断队列是否已满

int isQueueFull(const Queue* q) {

    return (q->rear + 1) % max == q->front;

}

// 入队

void enqueue(Queue* q, char elem) {

    if (isQueueFull(q)) {

        printf("队满\n");

        return;

    }

    q->data[q->rear] = elem;

    q->rear = (q->rear + 1) % max;

}

// 出队

char dequeue(Queue* q) {

    if (Empty(q)) {

        printf("队空\n");

        return '\0';

    }

    char elem = q->data[q->front];

    q->front = (q->front + 1) % max;

    return elem;

}

int main() {

    Queue q;

    initQueue(&q);

    // 判断队列是否非空

    printf("队列是空的吗? %s\n", Empty(&q) ? "Yes" : "No");

    // 进队元素a,b,c

    enqueue(&q, 'a');

    enqueue(&q, 'b');

    enqueue(&q, 'c');

    printf("出队: %c\n", dequeue(&q));

    // 进队元素d,e

    enqueue(&q, 'd');

    enqueue(&q, 'e');

    // 输出出队序列

    printf("出队: ");

    while (!Empty(&q)) {

        printf("%c ", dequeue(&q));

    }

    printf("\n");

    return 0;

}

  • 运行与测试(测试数据和实验结果分析

首先判断队列是否为空,然后三个元素a、b、c依次入队,然后a出队,d、e入队,然后全部出队,即显示b c d e,体现了队列先入先出的特点。如果出队输出结果时没能把入队的元素都输出出来,原因是一开始#define max 3,将符号常量 max 定义为 3但是入队d、e后有四个元素,队满了元素e就无法入队,出队时自然也看不见元素e

  • 总结与心得

  在进行队列数据结构实验的过程中,我对队列的概念和特点有了更深入的理解。队列是一种先进先出的数据结构,类似于排队等待服务的场景。队列的实现可以使用数组或链表,具体选择取决于实际需求。队列在实际应用中有广泛的用途,适用于需要按照先后顺序处理任务或数据的场景。通过实验,我深刻体会到了队列的优点和局限性。队列的入队和出队操作具有常数时间复杂度 O(1),因此在处理大量数据时表现出良好的性能。但是,队列的随机访问受限,只能从队首或队尾进行操作。

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、实验目的 1.了解图的存储结构和常用算法。 2.熟悉邻接矩阵和邻接表两种图的存储结构。 3.实现图的存储结构及其基本操作。 4.掌握图的遍历算法。 5.能够应用图的存储结构和算法解决实际问题。 二、实验内容 1.设计图的存储结构及其基本操作,包括图的创建、插入节点、插入边、删除节点、删除边等操作。 2.实现图的遍历算法,包括深度优先遍历和广度优先遍历。 3.编写应用程序,实现通过图的存储结构和算法解决实际问题,如求最短路径、拓扑排序等。 三、实验原理 1.图的定义:图是由顶点集合和边集合组成的一种数据结构。其中,顶点表示节点,边表示节点之间的连线。 2.图的分类:根据图的性质,可以分为有向图和无向图,带权图和无权图,稠密图和稀疏图等。 3.图的存储结构:常用的图的存储结构有邻接矩阵和邻接表两种。 (1)邻接矩阵:用一个二维数组表示节点之间的关系,其中,数组元素为1表示对应位置的两个节点之间有边,为0则没有。 (2)邻接表:用一个数组和链表表示节点之间的关系。数组中的每个元素表示一个节点,链表表示该节点与其它节点之间的连线。 4.图的遍历算法: (1)深度优先遍历(DFS):从图的某个节点出发,依次遍历其它节点,直到所有节点都被访问过。具体实现是使用递归或栈来实现。 (2)广度优先遍历(BFS):从图的某个节点出发,首先访问其周围的节点,然后再访问与之相邻的节点,直到所有节点都被访问过。具体实现是使用队列来实现。 5.图的应用: (1)最短路径:求两个节点之间的最短路径,常用的算法有 Dijkstra 算法和 Floyd 算法。 (2)拓扑排序:用于解决有向无环图中的任务调度问题,使得每个任务的前置任务都在其前面执行。 四、实验步骤 1.设计图的存储结构及其基本操作。 (1)创建图:根据用户输入的节点数和边数,创建邻接矩阵或邻接表。 (2)插入节点:向图中添加一个新节点。 (3)插入边:向图中添加一条新边。 (4)删除节点:从图中删除指定节点及其相关的所有边。 (5)删除边:从图中删除指定边。 2.实现图的遍历算法。 (1)深度优先遍历:使用递归或栈来实现。 (2)广度优先遍历:使用队列来实现。 3.编写应用程序,实现通过图的存储结构和算法解决实际问题。 (1)最短路径:使用 Dijkstra 算法或 Floyd 算法求解两个节点之间的最短路径。 (2)拓扑排序:使用拓扑排序算法解决任务调度问题。 五、实验结果 1.设计图的存储结构及其基本操作。 (1)邻接矩阵存储结构: ```c++ #define MAXVEX 100 #define INFINITY 65535 typedef struct { int vexs[MAXVEX]; int arc[MAXVEX][MAXVEX]; int numVertexes, numEdges; }MGraph; ``` (2)邻接表存储结构: ```c++ #define MAXVEX 100 #define INFINITY 65535 typedef struct EdgeNode { int adjvex; int weight; struct EdgeNode *next; }EdgeNode; typedef struct VertexNode { int in; int data; EdgeNode *firstedge; }VertexNode; typedef struct { VertexNode adjlist[MAXVEX]; int numVertexes, numEdges; }GraphAdjList; ``` 2.实现图的遍历算法。 (1)深度优先遍历: ```c++ void DFS(MGraph G, int i, bool visited[]) { visited[i] = true; printf("%d ", G.vexs[i]); for (int j = 0; j < G.numVertexes; j++) { if (G.arc[i][j] == 1 && !visited[j]) { DFS(G, j, visited); } } } void DFSTraverse(MGraph G) { bool visited[MAXVEX]; for (int i = 0; i < G.numVertexes; i++) { visited[i] = false; } for (int i = 0; i < G.numVertexes; i++) { if (!visited[i]) { DFS(G, i, visited); } } } ``` (2)广度优先遍历: ```c++ void BFSTraverse(MGraph G) { bool visited[MAXVEX]; for (int i = 0; i < G.numVertexes; i++) { visited[i] = false; } queue<int> q; for (int i = 0; i < G.numVertexes; i++) { if (!visited[i]) { visited[i] = true; printf("%d ", G.vexs[i]); q.push(i); while (!q.empty()) { int j = q.front(); q.pop(); for (int k = 0; k < G.numVertexes; k++) { if (G.arc[j][k] == 1 && !visited[k]) { visited[k] = true; printf("%d ", G.vexs[k]); q.push(k); } } } } } } ``` 3.编写应用程序,实现通过图的存储结构和算法解决实际问题。 (1)最短路径: ```c++ void Dijkstra(MGraph G, int v0, int dist[], int path[]) { bool final[MAXVEX]; for (int i = 0; i < G.numVertexes; i++) { final[i] = false; dist[i] = G.arc[v0][i]; if (dist[i] != INFINITY) { path[i] = v0; } else { path[i] = -1; } } dist[v0] = 0; final[v0] = true; for (int i = 1; i < G.numVertexes; i++) { int min = INFINITY; int k = 0; for (int j = 0; j < G.numVertexes; j++) { if (!final[j] && dist[j] < min) { min = dist[j]; k = j; } } final[k] = true; for (int j = 0; j < G.numVertexes; j++) { if (!final[j] && min + G.arc[k][j] < dist[j]) { dist[j] = min + G.arc[k][j]; path[j] = k; } } } } void ShortestPath_Dijkstra(MGraph G, int v0, int dist[], int path[]) { Dijkstra(G, v0, dist, path); for (int i = 0; i < G.numVertexes; i++) { printf("v%d -> v%d: ", v0, i); if (dist[i] == INFINITY) { printf("no path\n"); } else { int j = i; stack<int> s; while (j != v0) { s.push(j); j = path[j]; } s.push(v0); while (!s.empty()) { printf("v%d", s.top()); s.pop(); if (!s.empty()) { printf(" -> "); } } printf(", dist = %d\n", dist[i]); } } } ``` (2)拓扑排序: ```c++ bool TopologicalSort(GraphAdjList GL) { int count = 0; queue<int> q; for (int i = 0; i < GL.numVertexes; i++) { if (GL.adjlist[i].in == 0) { q.push(i); } } while (!q.empty()) { int i = q.front(); q.pop(); printf("%d ", GL.adjlist[i].data); count++; EdgeNode *p = GL.adjlist[i].firstedge; while (p != NULL) { int j = p->adjvex; if (--GL.adjlist[j].in == 0) { q.push(j); } p = p->next; } } printf("\n"); if (count < GL.numVertexes) { return false; } else { return true; } } ``` 六、实验结论 1.邻接矩阵和邻接表两种存储结构各有优缺点,应根据实际需求选择合适的存储结构。 2.深度优先遍历和广度优先遍历两种遍历算法都可以遍历图中的所有节点,具体应根据实际需求选择。 3.Dijkstra 算法和 Floyd 算法都可以求解最短路径问题,具体应根据图的规模和稠密程度选择合适的算法。 4.拓扑排序算法可以解决有向无环图中的任务调度问题,应用广泛。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值