Podczas usuwania węzła z dwojgiem dzieci, można wybrać jego następcę na zamówienie lub jego węzeł węzeł poprzednik zamówienie. W tym przypadku jest to znalezienie największej wartości w lewym sub-tree (czyli najbardziej po prawej dziecko swojego lewego sub-tree), co oznacza, że jest znalezienie węzła węzła w zamówienie poprzednika.
Po znalezieniu zastępczego węzła, w rzeczywistości nie usunąć węzeł który ma zostać usunięty. Zamiast wziąć wartość z węzłem następcy i przechowywać tę wartość w węźle, który chcesz usunąć. Następnie należy usunąć węzeł następcy. W ten sposób możesz zachować binarną Szukaj nieruchomości drzewo skoro można mieć pewność, że węzeł został wybrany będzie miał wartość, która jest niższa od wartości wszystkich dzieci w lewym sub-tree oryginalnego węzła, a większa, że od wartości wszystkich dzieci w odpowiednim sub-tree oryginalnego węzła.
EDYTOWAĆ
Po przeczytaniu pytanie trochę więcej, myślę, że znalazłem problem.
Zazwyczaj co masz oprócz deletefunkcji jest replacefunkcja, która zastępuje węzeł w pytaniu. Myślę, że trzeba zmienić ten wiersz kodu:
FindParent(largestValue).Right <- 0
do:
FindParent(largestValue).Right <- largestValue.Left
Jeśli largestValuewęzeł nie posiada lewy dziecko, po prostu dostać nulllub 0. Jeśli to ma lewy dziecka, że dziecko staje się zamiennikiem dla largestValuewęzła. Tak masz rację; kod nie bierze pod uwagę scenariusz, że largestValuewęzeł może mieć lewy dziecko.
Innym EDIT
Odkąd pisał tylko fragment, nie jestem pewien, co kontekst kodu jest. Ale jak pisał fragment wydaje się mieć problem proponujesz (zastąpił zły węzeł). Zazwyczaj istnieją trzy przypadki, ale zauważam, że komentarz w swoim fragmencie mówi //Case 4(więc może jest jakiś inny kontekst).
Wcześniej wspomniałem na fakt, że deletezazwyczaj pochodzi z replace. Więc jeśli znajdziesz largestValuewęzeł, należy go usunąć według dwóch prostych przypadkach (węzła bez dzieci i węzła z jednym dzieckiem). Więc jeśli szukasz w pseudo-kodu, aby usunąć węzeł z dwójką dzieci, to co zrobisz:
get largestValue from nodeToRemove.Left
nodeToRemove.Value <- largestValue.Value
//now replace largestValue with largestValue.Left
if largestValue = largestValue.Parent.Left then
largestValue.Parent.Left <- largestValue.Left //is largestValue a left child?
else //largestValue must be a right child
largestValue.Parent.Right <- largestValue.Left
if largestValue.Left is not null then
largestValue.Left.Parent <- largestValue.Parent
Uważam, że to dziwne, że struktury danych i algorytmy książka będzie opuścić tę część, więc jestem skłonny sądzić, że książka ma dodatkowo podzielone usunięcie na kilka więcej przypadków (ponieważ istnieją trzy standardowe przypadki), aby ułatwić Rozumiesz.
Aby udowodnić, że powyższy kod działa, należy rozważyć następujące drzewa:
8
/ \
7 9
Załóżmy, że chcesz usunąć 8. Starasz się znaleźć largestValueod nodeToRemove.Left. Daje to 7od lewa sub-drzewo ma tylko jedno dziecko.
Następnie należy zrobić:
nodeToRemove.Value <- largestValue.Value
Co znaczy:
8.value <- 7.Value
lub
8.Value <- 7
Więc teraz drzewo wygląda następująco:
7
/ \
7 9
Trzeba pozbyć węzła zastępczego i tak masz zamiar wymienić largestValuez largestValue.Left(co jest null). Więc najpierw dowiedzieć się, jakie dziecko 7jest:
if largestValue = largestValue.Parent.Left then
Co znaczy:
if 7 = 7.Parent.Left then
lub:
if 7 = 8.Left then
Od 7JEST 8lewej dziecka, trzeba wymienić 8.Leftz 7.Right( largestValue.Parent.Left <- largestValue.Left). Ponieważ 7nie ma dzieci, 7.Leftjest nieważna. Więc largestValue.Parent.Leftzostaje przydzielony na null (co skutecznie usuwa jego lewy dziecko). Więc oznacza to, że możesz skończyć z poniższego drzewa:
7
\
9