当前位置:   article > 正文

数据结构——01-抽奖数人-链表-实验题目与解答

数据结构——01-抽奖数人-链表-实验题目与解答

数据结构抽奖数人链表实验题目与解答

一、**实验题目**

抽奖游戏

n个人围成一圈,由第一个人开始,依次报数,数到第m人,便抽出来作为中奖人,然后从他的下一个人数起,数到第m人,再抽出来作为中奖人,如此循环,直到抽出k个为止。问哪些人中奖了。

每个人都有自己的编号,最后给出中奖人编号

完整代码在最后

二、**实验环境**

Windows 11

Visual Studio Code

三、**实验过程**

*顺序存储结构实现:*

*思路分析:*

创建一个大小为n的数组,用来存储所有人的编号

使用一个变量index来记录当前报数的位置。

使用一个变量k来记录当前还未中奖的人数。

当k>0时,从index开始循环数组,每数到第m个人,就将其编号输出,并从数组中移除该编号。

更新index为下一个未中奖人的位置。

当k=0时,结束循环。

代码:

img

img

在main函数中测试上述代码:

img

测试结果:

img

*链式存储结构实现:*

*思路分析:*

初始化链表,编号从1开始

如果首节点就是要找的数,则把首节点的下一个节点设为首节点

如果循环链表只剩一个元素,则删完之后要置为null

该链表需要一个data用于存储数据,一个指针指向下个节点

img

img

代码:

img

在main函数中测试上述代码:

img

测试结果:

img

四、**实验心得**

在本次实验中,我深入探索了数据结构的魅力,通过实现一个抽奖游戏,我不仅巩固了对顺序存储结构和链式存储结构的理解,还提升了我的编程实践能力。

首先,我根据实验要求,设计了一个抽奖游戏的算法。在这个游戏中,n个人围成一圈,从第一个人开始依次报数,每数到第m个人就将其抽出,直到抽出k个中奖人为止。

这个游戏规则简单,但背后却涉及到了数组和链表这两种基本数据结构的使用。 在实现顺序存储结构的版本时,我使用了一个大小固定的数组来存储参与者的编号。初始化数组时,我将每个人的编号依次赋值给数组的每个元素。在抽奖过程中,我通过循环和条件判断来模拟报数过程,并在每次报数到m时,输出中奖者的编号,并从数组中移除该编号。这个过程需要特别注意数组元素的移动和数组长度的更新。

接着,我尝试使用链式存储结构来实现同样的功能。与数组不同,链表可以动态地插入和删除节点。在抽奖过程中,我遍历链表,每数到第m个人,就删除当前节点并输出其编号。链表的动态特性使得删除操作变得更加直观和方便。

通过这次实验,我体会到了顺序存储结构和链式存储结构各自的优势和局限性。顺序存储结构在随机访问时效率较高,但插入和删除操作需要移动大量元素,而链式存储结构在插入和删除操作上更为高效,但随机访问时需要遍历链表。这两种数据结构的选择取决于具体问题的需求。

LinkCunChu:

 
  1. #include <iostream>
  2.  #include <vector>
  3.  ​
  4.  using namespace std;
  5.  ​
  6.  // 链式存储结构
  7.  ​
  8.  // 定义链表节点
  9.  typedef struct Node
  10.  { int data;
  11.   struct Node *next;
  12.  } Node;
  13.  ​
  14.  // 初始化链表
  15.  Node *InitLinkedList(int n)
  16.  { Node *head = NULL;
  17.   Node *prev = NULL;
  18.   for (int i = 0; i < n; ++i)
  19.   { Node *node = (Node *)malloc(sizeof(Node));
  20.   node->data = i + 1; // 编号从1开始
  21.   node->next = NULL;
  22.   if (head == NULL)
  23.   { head = node;
  24.   }
  25.   else
  26.   { prev->next = node;
  27.   }
  28.   prev = node;
  29.   }
  30.   prev->next = head; // 形成环形链表,方便循环取数
  31.   return head;
  32.  }
  33.  ​
  34.  // 删除链表中指定节点
  35.  void DeleteNode(Node **head, Node *target)
  36.  { if (*head == target) //如果首节点就是要找的数,则把首节点的下一个节点设为首节点
  37.   { if ((*head)->next == *head) //如果循环链表只剩一个元素,则删完之后要置为null
  38.   { free(*head);
  39.   *head = NULL;
  40.   }
  41.   else   //如果链表不止一个元素
  42.   { Node *temp = *head;
  43.   //获得首节点的前置节点
  44.   while (temp->next != *head)
  45.   { temp = temp->next;
  46.   }
  47.   //将头节点的前置节点与后趋节点相连
  48.   temp->next = (*head)->next;
  49.   free(*head);
  50.   *head = temp->next;
  51.   }
  52.   }
  53.   else
  54.   { Node *current = *head;
  55.   //获得要找的前驱节点
  56.   while (current->next != *head && current->next != target)
  57.   { current = current->next;
  58.   }
  59.   if (current->next == *head) //遍历完仍未找到目标点
  60.   { return;
  61.   }
  62.   Node *temp = current->next;
  63.   current->next = temp->next;
  64.   free(temp);
  65.   }
  66.  }
  67.  ​
  68.  // 求解中奖人编号
  69.  void resultLianShiList(int n, int m, int k)
  70.  { Node *head = InitLinkedList(n);
  71.   Node *current = head;
  72.   printf("中奖人编号:");
  73.   while (k > 0)
  74.   { //向后m个位置取数
  75.   for (int i = 0; i < m - 1; ++i)
  76.   { current = current->next;
  77.   }
  78.   Node *temp = current;
  79.   current = current->next;
  80.   printf("%d ", temp->data);
  81.   DeleteNode(&head, temp);
  82.   k--;
  83.   }
  84.   printf("\n");
  85.   // 释放链表节点
  86.   while (head != NULL)
  87.   { Node *temp = head;
  88.   head = head->next;
  89.   free(temp);
  90.   }
  91.  }
  92.  ​
  93.  int main()
  94.  { int n, m, k;
  95.   printf("游戏参与数n,报数间隔m,中奖人数k:");
  96.   scanf("%d", &n);
  97.   scanf("%d", &m);
  98.   scanf("%d", &k);
  99.   // 使用链式存储结构求解
  100.   printf("链式存储结构求解:\n");
  101.   resultLianShiList(n, m, k);
  102.  ​
  103.  }
  104.  ​

ShunXuCunChu:

  1.  #include <iostream>
  2.  #include <vector>
  3.  ​
  4.  using namespace std;
  5.  ​
  6.  typedef struct
  7.  { int data[1000];
  8.   int length;
  9.  } ShunXuList;
  10.  ​
  11.  // 初始化顺序表
  12.  void InitShunXuList(ShunXuList *L, int n)
  13.  { L->length = n;
  14.  //为每个元素添加编号
  15.   for (int i = 0; i < n; ++i)
  16.   { L->data[i] = i + 1;
  17.   }
  18.  }
  19.  ​
  20.  // 删除顺序表中指定位置的元素
  21.  void DeleteByIndex(ShunXuList *L, int index)
  22.  {
  23.  //index处开始将所有的元素 向前覆盖一位
  24.   for (int i = index; i < L->length - 1; ++i)
  25.   { L->data[i] = L->data[i + 1];
  26.   }
  27.  //长度减一
  28.   L->length--;
  29.  }
  30.  ​
  31.  // 求解中奖人编号
  32.  void resultShunXuList(int n, int m, int k)
  33.  { ShunXuList L;
  34.   InitShunXuList(&L, n);
  35.   int index = 0;
  36.   printf("中奖人编号:");
  37.   while (k > 0)
  38.   {
  39.  //向后数m个,因为自己也要算在内,所以要减一
  40.   index = (index + m - 1) % L.length;
  41.   printf("%d ", L.data[index]);
  42.  //删除已取
  43.   DeleteByIndex(&L, index);
  44.   k--;
  45.   }
  46.   printf("\n");
  47.  }
  48.  ​
  49.  int main()
  50.  { int n, m, k;
  51.   printf("游戏参与数n,报数间隔m,中奖人数k:");
  52.   scanf("%d", &n);
  53.   scanf("%d", &m);
  54.   scanf("%d", &k);
  55.  // 使用顺序存储结构求解
  56.   printf("顺序存储结构求解:\n");
  57.   resultShunXuList(n, m, k);
  58.  ​
  59.  }
  60.  ​

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/605265
推荐阅读
相关标签
  

闽ICP备14008679号