VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 273|回复: 4

[已解决]C语言数据结构-约瑟夫问题

[复制链接]
01_avatar_middle
最佳答案
0 
在线会员 发表于 2020-4-28 23:20:58 | 显示全部楼层 |阅读模式
本帖最后由 qiao141486 于 2020-4-28 23:24 编辑
  1. #ifndef CIRCLELINKLIST
  2. #define CIRCLELINKLIST

  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #define CIRCLELINKLIST_TRUE 1
  6. #define CIRCLELINKLIST_FALSE 0
  7. //链表小结点
  8. typedef struct CIRCLELINKNODE{
  9.         struct CIRCLELINKNODE * next;

  10. }CircleLinkNode;
  11. //链表结构体
  12. typedef struct CIRCLELINKLIST{
  13.         CircleLinkNode head;
  14.         int size;//判断循环是否停止的标志
  15. }CircleLinkList;

  16. //编写针对链表结构体操作的API函数

  17. //比较回调
  18. typedef void(*PRINTLINKLIST)(CircleLinkNode *);
  19. typedef int(*COMPARENODE)(CircleLinkNode *, CircleLinkNode *);

  20. //初始化函数
  21. CircleLinkList * Init_CircleLinkList();
  22. //插入函数
  23. void Insert_CircleLinkList(CircleLinkList * clist, int pos, CircleLinkNode* data);
  24. //根据位置删除
  25. void RemoveByPos_CircleLinkList(CircleLinkList * clist, int pos);
  26. //根据值删除函数
  27. void RemoveByValue_CircleLinkList(CircleLinkList * clist, CircleLinkNode * data, COMPARENODE compare);
  28. //获取链表的长度
  29. int Size_CircleLinkList(CircleLinkList * clist);
  30. //判断是否为空
  31. int IsEmpty_CircleLinkList(CircleLinkList * clist);
  32. //返回第一个元素
  33. CircleLinkNode *  Front_CircleLinkList(CircleLinkList * clist);
  34. int Find_CircleLinkList(CircleLinkList * clist, CircleLinkNode * data, COMPARENODE compare);
  35. //打印
  36. void Print_CircleLinkList(CircleLinkList * clist, PRINTLINKLIST print);
  37. //释放
  38. void FreeSpace_CircleLinkList(CircleLinkList  * clist);
  39. #endif
复制代码
  1. #include "CircleLinkList.h"

  2. //初始化函数
  3. CircleLinkList * Init_CircleLinkList(){

  4.         CircleLinkList *clist = (CircleLinkList *)malloc(sizeof(CircleLinkList));
  5.         clist->head.next = &(clist->head);//指向自己
  6.         clist->size = 0;
  7.         return clist;
  8. }
  9. //插入函数
  10. void Insert_CircleLinkList(CircleLinkList * clist, int pos, CircleLinkNode* data){
  11.         if (clist == NULL)
  12.         {
  13.                 return;
  14.         }
  15.         if (data == NULL)
  16.         {
  17.                 return;
  18.         }
  19.         if (pos < 0 || pos >= clist->size)
  20.         {
  21.                 pos = clist->size;
  22.         }
  23.         //根据位置查找结点
  24.         //辅助指针变量
  25.         CircleLinkNode * pCurrent = &(clist->head);
  26.         for (int i = 0; i < pos; i++)
  27.         {
  28.                 pCurrent = pCurrent->next;
  29.         }
  30.         data->next = pCurrent->next;
  31.         pCurrent->next = data;

  32.         clist->size++;

  33. }
  34. //根据位置删除
  35. void RemoveByPos_CircleLinkList(CircleLinkList * clist, int pos){
  36.         if (clist == NULL)
  37.         {
  38.                 return;
  39.         }
  40.         if (pos < 0 || pos >= clist->size){
  41.                 return;
  42.         }
  43.         CircleLinkNode  * pCurrent = &(clist->head);
  44.         for (int i = 0; i < pos; i++){
  45.                 pCurrent = pCurrent->next;
  46.         }
  47.         //缓存当前结点的下一个结点
  48.         CircleLinkNode * pNext = pCurrent->next;
  49.         pCurrent->next = pNext->next;
  50.         clist->size--;

  51. }
  52. //根据值删除函数
  53. void RemoveByValue_CircleLinkList(CircleLinkList * clist, CircleLinkNode * data, COMPARENODE compare){
  54.         if (clist == NULL){
  55.                 return;
  56.         }
  57.         if (data == NULL){
  58.                 return;
  59.         }
  60.         CircleLinkNode * pPrev = &(clist->head);
  61.         CircleLinkNode * pCurrent = pPrev->next;
  62.         int i = 0;
  63.         for (i = 0; i < clist->size; i++){
  64.                 if (compare(pCurrent, data) == CIRCLELINKLIST_TRUE)
  65.                 {
  66.                         pPrev->next = pCurrent->next;
  67.                         break;

  68.                 }
  69.                 pPrev = pCurrent;
  70.                 pCurrent = pPrev->next;
  71.         }

  72.         clist->size--;

  73. }
  74. //获取链表的长度
  75. int Size_CircleLinkList(CircleLinkList * clist){
  76.         return clist->size;
  77. }
  78. //判断是否为空
  79. int IsEmpty_CircleLinkList(CircleLinkList * clist){
  80.         if (clist->size == 0)
  81.         {
  82.                 return CIRCLELINKLIST_TRUE;
  83.         }
  84.         return CIRCLELINKLIST_FALSE;
  85. }
  86. //返回第一个元素
  87. CircleLinkNode *  Front_CircleLinkList(CircleLinkList * clist){

  88.         return clist->head.next;
  89. }
  90. //查找
  91. int Find_CircleLinkList(CircleLinkList * clist, CircleLinkNode * data, COMPARENODE compare){
  92.         if (clist == NULL)
  93.         {
  94.                 return -1;
  95.         }
  96.         if (data == NULL)
  97.         {
  98.                 return -1;
  99.         }

  100.         CircleLinkNode * pCurrent = clist->head.next;

  101.         int flag = -1;
  102.         for (int i = 0; i < clist->size; i++)
  103.         {
  104.                 if (compare(pCurrent, data) == CIRCLELINKLIST_TRUE){
  105.                         flag = i;
  106.                         break;
  107.                 }
  108.                 pCurrent = pCurrent->next;
  109.         }

  110.         return flag;
  111. }


  112. //打印
  113. void Print_CircleLinkList(CircleLinkList * clist, PRINTLINKLIST print){
  114.         if (clist == NULL){

  115.                 return;
  116.         }
  117.         CircleLinkNode * pCurrent = clist->head.next;
  118.         for (int i = 0; i < clist->size; i++){
  119.                 if (pCurrent == &(clist->head))
  120.                 {
  121.                         pCurrent = pCurrent->next;
  122.                         printf("-------------------------- \n");
  123.                 }
  124.                 print(pCurrent);
  125.                 pCurrent = pCurrent->next;
  126.         }

  127. }
  128. void FreeSpace_CircleLinkList(CircleLinkList  * clist)
  129. {
  130.         if (clist == NULL){

  131.                 return;
  132.         }
  133.         free(clist);

  134. }
复制代码
  1. #define _CRT_CECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "CircleLinkList.h"
  6. #define M 8
  7. #define N 3
  8. typedef struct MYNUM {
  9.         CircleLinkNode node;
  10.         int val;
  11. }MyNum;
  12. void MyPrint(CircleLinkList * data){
  13.         MyNum* num = (MyNum*)data;
  14.         printf("%d ", num->val);
  15. }
  16. int MyCompare(CircleLinkNode * data1, CircleLinkNode * data2){
  17.             MyNum * num1 = (MyNum*)data1;
  18.                 MyNum* num2 = (MyNum*)data2;
  19.                 if (num1->val == num2->val){
  20.                         CIRCLELINKLIST_TRUE;
  21.                 }
  22.                 CIRCLELINKLIST_FALSE;
  23.                 return  0;
  24. }
  25. int main(void){

  26.         CircleLinkList * clist = Init_CircleLinkList();

  27.         MyNum num[M];
  28.         for (int i = 0; i < 8; i++){

  29.                 num[i].val = i + 1;
  30.                 Insert_CircleLinkList(clist, i, (CircleLinkNode *)&num[i]);
  31.         }
  32.         Print_CircleLinkList(clist, MyPrint);
  33.         printf("\n");
  34.         //FreeSpace_CircleLinkList(clist);
  35.         //辅助指针
  36.         int index = 1;
  37.         CircleLinkNode * pCurrent = clist->head.next;
  38.         while (Size_CircleLinkList(clist) > 1){
  39.                 if (index == N){
  40.                 MyNum* temNum = (MyNum*)pCurrent;
  41.                 printf("%d ", temNum->val);
  42.                 //缓存待删除结点的下一个结点
  43.                 CircleLinkNode * pNext = pCurrent->next;
  44.                 //根据值去删除
  45.                 RemoveByValue_CircleLinkList(clist, pCurrent, MyCompare);
  46.                   pCurrent = pNext;
  47.                   if (pCurrent == &(clist->head)){
  48.                           pCurrent = pCurrent->next;
  49.                   }
  50.                   index = 1;
  51.                 }
  52.                 pCurrent = pCurrent->next;
  53.                 if (pCurrent == &(clist->head)){
  54.                         pCurrent = pCurrent->next;
  55.                 }
  56.                 index++;
  57.         }
  58.         if (Size_CircleLinkList(clist) == 1){
  59.                 MyNum *tempNum = (MyNum*)Front_CircleLinkList(clist);
  60.                 printf("%d ", tempNum->val);
  61.         }
  62.         else{
  63.                 printf("出错了!");
  64.         }
  65.         printf("\n");
  66.         FreeSpace_CircleLinkList(clist);
  67.         getchar();
  68.         getchar();
  69.         return 0;
  70. }
复制代码

运行的结果不对,,我自己调试了调试,但找不到错误在哪,请教各位大佬同学
最佳答案
57_avatar_small
2020-4-29 11:45:52
qiao141486 发表于 2020-4-29 10:43
是我展示出来图片的代码,我黏贴复制上去的,我自己运行时,也没有出这些错误。吧CircleLinkList换成Circ ...

在while循环中把pCurrent的数值先打印一下,发现你的删除函数是有问题的。节点并没有将数据删除。
f5f2d4983091a9fab7790a7660ed6c4.png




上一篇:使用c++进行Excel文档的读写
下一篇:vs2013当中已经和syc老师一样设置了环境为什么还会出现下面的问题?
57_avatar_middle
最佳答案
21 
在线会员 发表于 2020-4-29 09:46:05 | 显示全部楼层
第一个问题,楼主上传的代码是编译不过的,main.cpp中的Print_CircleLinkList(clist,MyPrint);会报错。
错误信息:
error C2664: “void Print_CircleLinkList(CircleLinkList *,PRINTLINKLIST)”: 无法将参数 2 从“void (__cdecl *)(CircleLinkList *)”转换为“PRINTLINKLIST”
查看代码后发现函数指针使用有问题。我们发现MyPrint的参数为CircleLinkList * ,而函数指针的参数类型为CircleLinkNode *。
其次MyPrint函数中,为什么要将CircleLinkList *强制转换为MYNUM*,然后再获取value?不可以直接使用printf("%d ", data->size);?
请问您所展示的图片是运行您展示的代码所运行出来的吗?
  1. typedef void(*PRINTLINKLIST)(CircleLinkNode *);

  2. //打印
  3. void Print_CircleLinkList(CircleLinkList * clist, PRINTLINKLIST print);

  4. //打印
  5. void Print_CircleLinkList(CircleLinkList * clist, PRINTLINKLIST print) {
  6.         if (clist == NULL) {

  7.                 return;
  8.         }
  9.         CircleLinkNode * pCurrent = clist->head.next;
  10.         for (int i = 0; i < clist->size; i++) {
  11.                 if (pCurrent == &(clist->head))
  12.                 {
  13.                         pCurrent = pCurrent->next;
  14.                         printf("-------------------------- \n");
  15.                 }
  16.                 print(pCurrent);
  17.                 pCurrent = pCurrent->next;
  18.         }

  19. }

  20. void MyPrint(CircleLinkList * data) {
  21.         MyNum* num = (MyNum*)data;
  22.         printf("%d ", num->val);
  23. }

  24. typedef struct MYNUM {
  25.         CircleLinkNode node;
  26.         int val;
  27. }MyNum;

  28. //链表结构体
  29. typedef struct CIRCLELINKLIST {
  30.         CircleLinkNode head;
  31.         int size;//判断循环是否停止的标志
  32. }CircleLinkList;

复制代码
01_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2020-4-29 10:43:55 | 显示全部楼层
JLDawson 发表于 2020-4-29 09:46
第一个问题,楼主上传的代码是编译不过的,main.cpp中的Print_CircleLinkList(clist,MyPrint);会报错。
错 ...

是我展示出来图片的代码,我黏贴复制上去的,我自己运行时,也没有出这些错误。
  1. void MyPrint(CircleLinkNode * data){
  2.         MyNum* num = (MyNum*)data;
  3.         printf("%d ", num->val);
  4. }
复制代码
吧CircleLinkList换成CircleLinkNode,因为循环列表中,数据是用结点串起来的,打印数据时就要把结点型数据转换成自己定义成的数据
57_avatar_middle
最佳答案
21 
在线会员 发表于 2020-4-29 11:45:52 | 显示全部楼层    本楼为最佳答案   
bestAnswer
qiao141486 发表于 2020-4-29 10:43
是我展示出来图片的代码,我黏贴复制上去的,我自己运行时,也没有出这些错误。吧CircleLinkList换成Circ ...

在while循环中把pCurrent的数值先打印一下,发现你的删除函数是有问题的。节点并没有将数据删除。
01_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2020-4-29 12:22:34 | 显示全部楼层
JLDawson 发表于 2020-4-29 11:45
在while循环中把pCurrent的数值先打印一下,发现你的删除函数是有问题的。节点并没有将数据删除。

谢谢这位大佬同学,我自己调试时似乎也感觉到了,就是不太确定
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )|网站地图wx_jqr

GMT+8, 2020-8-11 23:51

Powered by CcTry.CoM

© 2009-2020 cctry.com

快速回复 返回顶部 返回列表