Jedes 2. Element aus einem Binärbaum löschen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Jedes 2. Element aus einem Binärbaum löschen

    Hallo,

    stehe vor folgendem Problem:
    Ich habe einen BBaum aufgebaut (nicht balanciert!!!) und stehe jetzt vor dem Problem jedes 2. Element aus diesem Baum zu löschen.

    Hab mir das so vorgestellt,
    das ich mir den Baum traversieren lasse und dann jedes 2. Element lösche (habe neben den Nutzdaten in jedem Element auch noch nen Zähler stehen der mir angibt wann das Element eingefügt wurde) und an dessen Stelle das kleinste Element des rechten Teilbaumes hinsetze.
    Soweit ist das ja nicht so schwierig,
    aber wie komme ich an den Vorgänger des jeweils 2. Elements???

    Ich muss ja den Zeiger des Vorgängers des jeweils 2. Elements umhängen, stehe aber vor dem Problem wie komme ich zum Vorgänger.

    Bin für jeden Tip (oder URL) dankbar :D


    P.S.: Wie schon gesagt ist der Baum nicht balanciert, und muss auch nach dem Löschen nicht balanciert sein.
  • baum.h

    Quellcode

    1. #ifndef _BAUM_
    2. #define _BAUM_
    3. #include <iostream>
    4. using namespace std;
    5. class Blatt
    6. {
    7. public:
    8. Blatt(const char*, const char*);
    9. ~Blatt();
    10. const char* getSchluessel(){return schluessel;}
    11. const char* getWert(){return wert;}
    12. void setZaehler(void);
    13. //bool operator<(Blatt &obj){return (strcmp(this->schluessel, obj.schluessel) < 0);}
    14. //bool operator==(Blatt &obj){return (strcmp(this->schluessel, obj.schluessel) == 0);}
    15. private:
    16. char schluessel[30];
    17. char *wert;
    18. int zaehler;
    19. int tiefe;
    20. Blatt *links, *rechts;
    21. friend class Baum;
    22. };
    23. class Baum
    24. {
    25. public:
    26. void add(Blatt *);
    27. void addRekursive(bool, Blatt *, Blatt *);
    28. void remove(Blatt *);
    29. const char * operator[](const char *);
    30. void maxTiefeErmittlung(Blatt *);
    31. void maxSuchweg(const char *, Blatt *);
    32. void inorder2(Blatt *);
    33. void jeden2tenLoeschen(Blatt *);
    34. };
    35. Blatt *anker = 0;
    36. static int maxTiefe = 0;
    37. char maxTiefeElement[30];
    38. #endif
    Alles anzeigen


    baum.cpp

    Quellcode

    1. #include "baum.h"
    2. #include <iostream>
    3. #include <assert.h>
    4. #include <crtdbg.h>
    5. using namespace std;
    6. int main()
    7. {
    8. Baum b;
    9. Blatt *keyValue1 = new Blatt("L", "01. Wert");
    10. Blatt *keyValue2 = new Blatt("J", "02. Wert");
    11. Blatt *keyValue3 = new Blatt("N", "03. Wert");
    12. Blatt *keyValue4 = new Blatt("D", "04. Wert");
    13. Blatt *keyValue5 = new Blatt("K", "05. Wert");
    14. Blatt *keyValue6 = new Blatt("M", "06. Wert");
    15. Blatt *keyValue7 = new Blatt("O", "07. Wert");
    16. Blatt *keyValue8 = new Blatt("C", "08. Wert");
    17. Blatt *keyValue9 = new Blatt("E", "09. Wert");
    18. Blatt *keyValue10 = new Blatt("P", "10. Wert");
    19. Blatt *keyValue11 = new Blatt("A", "11. Wert");
    20. Blatt *keyValue12 = new Blatt("B", "12. Wert");
    21. Blatt *keyValue13 = new Blatt("H", "13. Wert");
    22. Blatt *keyValue14 = new Blatt("Q", "14. Wert");
    23. Blatt *keyValue15 = new Blatt("G", "15. Wert");
    24. Blatt *keyValue16 = new Blatt("I", "16. Wert");
    25. Blatt *keyValue17 = new Blatt("F", "17. Wert");
    26. Blatt *keyValue18 = new Blatt("R", "18. Wert");
    27. Blatt *keyValue19 = new Blatt("S", "19. Wert");
    28. Blatt *keyValue20 = new Blatt("X", "20. Wert");
    29. b.add(keyValue1);
    30. b.add(keyValue2);
    31. b.add(keyValue3);
    32. b.add(keyValue4);
    33. b.add(keyValue5);
    34. b.add(keyValue6);
    35. b.add(keyValue7);
    36. b.add(keyValue8);
    37. b.add(keyValue9);
    38. b.add(keyValue10);
    39. b.add(keyValue11);
    40. b.add(keyValue12);
    41. b.add(keyValue13);
    42. b.add(keyValue14);
    43. b.add(keyValue15);
    44. b.add(keyValue16);
    45. b.add(keyValue17);
    46. b.add(keyValue18);
    47. b.add(keyValue19);
    48. b.add(keyValue20);
    49. delete keyValue1;
    50. delete keyValue2;
    51. delete keyValue3;
    52. delete keyValue4;
    53. delete keyValue5;
    54. delete keyValue6;
    55. delete keyValue7;
    56. delete keyValue8;
    57. delete keyValue9;
    58. delete keyValue10;
    59. delete keyValue11;
    60. delete keyValue12;
    61. delete keyValue13;
    62. delete keyValue14;
    63. delete keyValue15;
    64. delete keyValue16;
    65. delete keyValue17;
    66. delete keyValue18;
    67. delete keyValue19;
    68. delete keyValue20;
    69. _CrtDumpMemoryLeaks();
    70. }
    71. /////////////////////////////////////////////////////////
    72. /////////////////////////////////////////////////////////
    73. Blatt::Blatt(const char *key, const char *value)
    74. {
    75. size_t keyLen = strlen(key) + 1;
    76. strcpy_s(schluessel, keyLen, key);
    77. size_t valueLen = strlen(value) + 1;
    78. wert = new char[valueLen];
    79. assert(wert);
    80. strcpy_s(wert, valueLen, value);
    81. links = 0;
    82. rechts = 0;
    83. }
    84. Blatt::~Blatt()
    85. {
    86. if (anker)
    87. {
    88. delete[] wert;
    89. }
    90. }
    91. void Blatt::setZaehler()
    92. {
    93. static int counter = 1;
    94. zaehler = counter;
    95. counter++;
    96. }
    97. /////////////////////////////////////////////////////////
    98. /////////////////////////////////////////////////////////
    99. void Baum::add(Blatt *obj)
    100. {
    101. if (anker == 0)
    102. {
    103. obj->setZaehler();
    104. obj->tiefe = 0;
    105. maxTiefeErmittlung(obj);
    106. anker = obj;
    107. //cout << "eingefuegt :: " << obj->schluessel << " :: nr:" << obj->zaehler << endl;
    108. return;
    109. }
    110. else
    111. {
    112. if (strcmp(obj->schluessel, anker->schluessel) < 0)
    113. {
    114. //links
    115. //cout << "Linker Teilbaum:" << endl;
    116. addRekursive(1, anker, obj);
    117. return;
    118. }
    119. else
    120. {
    121. //rechts
    122. //cout << "Rechter Teilbaum:" << endl;
    123. addRekursive(0, anker, obj);
    124. return;
    125. }
    126. }
    127. }
    128. void Baum::addRekursive(bool left, Blatt *pos, Blatt *obj) //bool left = 1 -> links einfügen
    129. {
    130. Blatt *hilfszeiger = pos;
    131. static int tiefe = 1;
    132. //Blatt wird links eingefügt (bool left = 1)
    133. if (left)
    134. {
    135. //linke Position frei
    136. if (hilfszeiger->links == 0)
    137. {
    138. obj->setZaehler();
    139. obj->tiefe = tiefe;
    140. maxTiefeErmittlung(obj);
    141. hilfszeiger->links = obj;
    142. //cout << "Tiefe:" << tiefe << " :: links eingefuegt :: " << obj->schluessel << " :: nr:" << obj->zaehler << endl;
    143. tiefe = 1;
    144. return;
    145. }
    146. else
    147. {
    148. //linke Position besetzt, also erneut vergleichen
    149. if (strcmp(obj->schluessel, hilfszeiger->links->schluessel) < 0)
    150. {
    151. //cout << "Tiefe:" << tiefe << endl;
    152. tiefe++;
    153. addRekursive(1, hilfszeiger->links, obj);
    154. return;
    155. }
    156. else
    157. {
    158. //cout << "Tiefe:" << tiefe << endl;
    159. tiefe++;
    160. addRekursive(0, hilfszeiger->links, obj);
    161. return;
    162. }
    163. }
    164. }
    165. //Blatt wird rechts eingefügt (bool left = 0)
    166. else
    167. {
    168. if (hilfszeiger->rechts == 0)
    169. {
    170. obj->setZaehler();
    171. obj->tiefe = tiefe;
    172. maxTiefeErmittlung(obj);
    173. hilfszeiger->rechts = obj;
    174. //cout << "Tiefe:" << tiefe << " :: rechts eingefuegt :: " << obj->schluessel << " :: nr:" << obj->zaehler << endl;
    175. tiefe = 1;
    176. return;
    177. }
    178. else
    179. {
    180. if (strcmp(obj->schluessel, hilfszeiger->rechts->schluessel) < 0)
    181. {
    182. //cout << "Tiefe:" << tiefe << endl;
    183. tiefe++;
    184. addRekursive(1, hilfszeiger->rechts, obj);
    185. return;
    186. }
    187. else
    188. {
    189. //cout << "Tiefe:" << tiefe << endl;
    190. tiefe++;
    191. addRekursive(0, hilfszeiger->rechts, obj);
    192. return;
    193. }
    194. }
    195. }
    196. }
    197. const char * Baum::operator[](const char *key)
    198. {
    199. static Blatt *hilfszeiger;
    200. static bool rekursiverAufruf = false;
    201. static bool nichtInListe;
    202. if (!rekursiverAufruf)
    203. {
    204. hilfszeiger = anker;
    205. nichtInListe = false;
    206. }
    207. if (hilfszeiger)
    208. {
    209. if (strcmp(key, hilfszeiger->schluessel) == 0)
    210. {
    211. rekursiverAufruf = false;
    212. return hilfszeiger->wert;
    213. }
    214. else
    215. {
    216. if (strcmp(key, hilfszeiger->schluessel) < 0)
    217. {
    218. if (hilfszeiger->links != 0)
    219. {
    220. hilfszeiger = hilfszeiger->links;
    221. rekursiverAufruf = true;
    222. operator[](key);
    223. }
    224. else
    225. {
    226. nichtInListe = true;
    227. }
    228. }
    229. else
    230. {
    231. if (hilfszeiger->rechts != 0)
    232. {
    233. hilfszeiger = hilfszeiger->rechts;
    234. rekursiverAufruf = true;
    235. operator[](key);
    236. }
    237. else
    238. {
    239. nichtInListe = true;
    240. }
    241. }
    242. }
    243. }
    244. if (nichtInListe)
    245. {
    246. rekursiverAufruf = false;
    247. return "Nicht in Liste";
    248. }
    249. else
    250. {
    251. return hilfszeiger->wert;
    252. }
    253. }
    254. void Baum::maxTiefeErmittlung(Blatt *obj)
    255. {
    256. size_t keyLen = strlen(obj->schluessel) + 1;
    257. if (obj->tiefe > maxTiefe)
    258. {
    259. maxTiefe = obj->tiefe;
    260. strcpy_s(maxTiefeElement, keyLen, obj->schluessel);
    261. }
    262. }
    263. void Baum::maxSuchweg(const char *key, Blatt *obj)
    264. {
    265. static bool rekursiverAufruf = false;
    266. static Blatt *hilfszeiger;
    267. static int suchschritte;
    268. if (!rekursiverAufruf)
    269. {
    270. hilfszeiger = anker;
    271. suchschritte = 1;
    272. cout << "Maximalen Suchweg fuer Element " << maxTiefeElement << " ermitteln" << endl;
    273. }
    274. if (hilfszeiger)
    275. {
    276. if (strcmp(key, hilfszeiger->schluessel) == 0)
    277. {
    278. cout << "Gesuchtes Element(" << hilfszeiger->schluessel << " -> " << hilfszeiger->wert << ") gefunden!" << endl;
    279. cout << "Anzahl Suchschritte: " << suchschritte << endl;
    280. }
    281. else
    282. {
    283. if (strcmp(key, hilfszeiger->schluessel) < 0)
    284. {
    285. cout << hilfszeiger->schluessel << " -> " << hilfszeiger->wert << endl;
    286. hilfszeiger = hilfszeiger->links;
    287. rekursiverAufruf = true;
    288. suchschritte++;
    289. maxSuchweg(key, hilfszeiger);
    290. }
    291. else
    292. {
    293. cout << hilfszeiger->schluessel << " -> " << hilfszeiger->wert << endl;
    294. hilfszeiger = hilfszeiger->rechts;
    295. rekursiverAufruf = true;
    296. suchschritte++;
    297. maxSuchweg(key, hilfszeiger);
    298. }
    299. }
    300. }
    301. }
    302. void Baum::inorder2(Blatt *obj) //traversiert inorder und ruft die Methode 'jeden2tenLoeschen(Blatt *)' auf
    303. {
    304. Blatt *hilfszeiger = obj;
    305. if (hilfszeiger->links)
    306. {
    307. inorder2(hilfszeiger->links);
    308. }
    309. jeden2tenLoeschen(hilfszeiger);
    310. if (hilfszeiger->rechts)
    311. {
    312. inorder2(hilfszeiger->rechts);
    313. }
    314. }
    315. void Baum::jeden2tenLoeschen(Blatt *obj)
    316. {
    317. if (obj->zaehler % 2 == 0)
    318. {
    319. cout << obj->schluessel << " :: " << obj->zaehler << endl;
    320. }
    321. }
    Alles anzeigen


    Beispiel:
    Möchte die 6 löschen, dann setze ich die 7 an dessen Stelle.
    Aber dafür muss ich den rechten Zeiger der 3 umsetzen.
    Aber wie komme ich zur 3???
    Bilder
    • baum.JPG

      6,33 kB, 512×384, 255 mal angesehen
  • :D
    Habe über dem Problem die grundlegende Eigenschaft des Binärbaumes vergessen.

    Hab jetzt ne Möglichkeit gefunden, mein Problem zu lösen.
    Da ich aber noch etwas Zeit habe die Aufgabe zu lösen mach ich mich jetzt nicht an die Aufgabe.


    Trotzdem dank an alle die sich mit dem Problem beschäftigt haben :!:


    :) Ich wünsche Allen schöne Feiertage und nen guten Rutsch :)