Für Vorlesungen, bitte die Webseite verwenden. https://flavigny.de/lecture
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.1KB

  1. #include<stdio.h>
  2. // Ein Listenelement
  3. struct IntListElem {
  4. IntListElem* next; // Zeiger auf nächstes Element
  5. int value; // Daten zu diesem Element
  6. } ;
  7. // Eine Liste
  8. struct IntList {
  9. int count; // Anzahl Elemente in der Liste
  10. IntListElem* first; // Zeiger auf erstes Element der Liste
  11. } ;
  12. // Initialisiere eine Listenstruktur
  13. void empty_list (IntList* l)
  14. {
  15. l->first = 0; // 0 ist keine gueltige Adresse: Liste ist leer
  16. l->count = 0;
  17. }
  18. // Fuege ein Element nach einem gegebenem ein
  19. void insert_in_list (IntList* list, IntListElem* where, IntListElem* ins)
  20. {
  21. if (where==0) // fuege am Anfang ein
  22. {
  23. ins->next = list->first;
  24. list->first = ins;
  25. list->count = list->count + 1;
  26. }
  27. else // fuege nach where ein
  28. {
  29. ins->next = where->next;
  30. where->next = ins;
  31. list->count = list->count + 1;
  32. }
  33. }
  34. // Entferne ein Element nach einem gegebenem
  35. // Liefere das entfernte Element zurueck
  36. IntListElem* remove_from_list (IntList* list, IntListElem* where)
  37. {
  38. IntListElem* p; // das entfernte Element
  39. // where==0 dann entferne erstes Element
  40. if (where==0)
  41. {
  42. p = list->first;
  43. if (p!=0)
  44. {
  45. list->first = p->next;
  46. list->count = list->count - 1;
  47. }
  48. return p;
  49. }
  50. // entferne Element nach where
  51. p = where->next;
  52. if (p!=0)
  53. {
  54. where->next = p->next;
  55. list->count = list->count - 1;
  56. }
  57. return p;
  58. }
  59. // creates a cyclic list with a linear part of k elements
  60. // and a cyclic part of n elements
  61. IntList* make_cyclic_list(int k, int n) {
  62. IntList* list = new IntList();
  63. empty_list(list);
  64. // create cyclic list of length n
  65. if (n > 0) {
  66. // create last element of list (its inserted first)
  67. IntListElem* last = new IntListElem();
  68. last->value = n+k;
  69. // insert the (now first, but later) last element into the list
  70. insert_in_list(list, 0, last);
  71. // now iterate over every other number
  72. for (int i = n+k-1; i > k; i--) {
  73. // and create a new list element
  74. IntListElem* elem = new IntListElem();
  75. // with the given number
  76. elem->value = i;
  77. // and add it to the list in the very beginning
  78. insert_in_list(list, 0, elem);
  79. }
  80. // make the last element reference the first one
  81. last->next = list->first;
  82. }
  83. IntListElem* firstCyclic = list->first;
  84. // add a linear part
  85. for (int i = k; i > 0; i--) {
  86. // create new list element
  87. IntListElem* elem = new IntListElem();
  88. // with given value
  89. elem->value = i;
  90. // and insert in the very beginning
  91. insert_in_list(list, 0, elem);
  92. // if it is the (first inserted, but later) last element of the linear
  93. // part, make it point to the first cyclic element
  94. if (i == k) {
  95. elem->next = firstCyclic;
  96. }
  97. }
  98. return list;
  99. }
  100. // Hase-Igel Algorithmus zum Finden eines Zyklus in einer Liste
  101. int hase_igel(IntList* list) {
  102. // create igel, that goes on by one
  103. IntListElem* igel = list->first;
  104. // create hase that always skips one element
  105. IntListElem* hase = list->first;
  106. // count the number of steps needed
  107. int n = 0;
  108. // this is the first occurence of a cycle
  109. int first = 0;
  110. // move forward with igel and hase until we hit the end of the list
  111. while (igel != 0 && hase != 0) {
  112. // increment igel and hase
  113. igel = igel->next;
  114. hase = hase->next->next;
  115. // increment the step counter
  116. n++;
  117. // if igel and hase point to the same element, there
  118. // has to be a cycle
  119. if (igel == hase) {
  120. // save the first occurence
  121. if (first == 0) {
  122. first = n;
  123. // if we find the second one, return the difference
  124. } else {
  125. return n - first;
  126. }
  127. }
  128. }
  129. // if there is an end, there can't be a cycle
  130. return 0;
  131. }
  132. int main() {
  133. IntList* list = make_cyclic_list(10, 0);
  134. printf("Laenge des Zyklus: %d\n", hase_igel(list));
  135. }