// File: /workspace/github_cpp_makefile_star2_O1/DaCasBe[P]Gestion-de-asignaturas-mediante-arboles-binarios-ordenados/nodoEnlazadoArbolBinarioEstudiante.cpp
// Function: ed::NodoEnlazadoArbolBinarioEstudiante::remove(ed::Estudiante const&)
void ed::NodoEnlazadoArbolBinarioEstudiante::remove(ed::Estudiante const &item){
	ed::Estudiante e(item); //Creamos un estudiante auxiliar
	
	//Precondición
	#ifndef NDEBUG
		assert(exists(e));
	#endif
	
	if(item==getItem()){ //El nodo actual contiene el ítem a eliminar
		ed::NodoEnlazadoArbolBinarioEstudiante * auxiliar; //Creamos un nodo auxiliar
		
		if(!hasLeftTree() and !hasRightTree()){ //El nodo actual no tiene hijos
			if(hasParent()){ //El nodo actual tiene padre
				if(getParent()->getLeftTree()==this){ //El nodo actual es el hijo izquierdo de su padre
					getParent()->setLeftTree(NULL);
				}

				else{ //El nodo actual es el hijo derecho de su padre
					getParent()->setRightTree(NULL);
				}
				
				//Borramos el ítem del nodo actual
				delete _item;
				_item=NULL;
			}
			
			else{ //El nodo atual no tiene padre
				//Borramos el ítem del nodo actual
				_item=NULL;
			}
		}

		else if(hasLeftTree() and !hasRightTree()){ //El nodo actual sólo tiene hijo izquierdo
			if(hasParent()){ //El nodo actual tiene padre
				if(getParent()->getLeftTree()==this){ //El nodo actual es el hijo izquierdo de su padre
					getParent()->setLeftTree(getLeftTree());
				}

				else{ //El nodo actual es el hijo derecho de su padre
					getParent()->setRightTree(getLeftTree());
				}
				
				getLeftTree()->setParent(getParent()); //Enlazamos el hijo del nodo actual con el padre de este
				
				_item=NULL; //Borramos el ítem el nodo actual
				
				//Desenlazamos y borramos el nodo actual
				auxiliar=this;
				auxiliar->setParent(NULL);
				auxiliar->setLeftTree(NULL);
				
				delete auxiliar;
			}

			else{ //El nodo actual no tiene padre
				*this=*getLeftTree(); //Hacemos que el nodo actual sea el hijo
				
				//Desenlazamos el nodo actual
				getParent()->setLeftTree(NULL);
				setParent(NULL);
			}
		}

		else if(!hasLeftTree() and hasRightTree()){ //El nodo actual sólo tiene hijo derecho
			if(hasParent()){ //El nodo actual tiene padre

				if(getParent()->getLeftTree()==this){ //El nodo actual es el hijo izquierdo de su padre
					getParent()->setLeftTree(getRightTree());
				}

				else{ //El nodo actual es el hijo derecho de su padre
					getParent()->setRightTree(getRightTree());
				}

				getRightTree()->setParent(getParent()); //Enlazamos el hijo del nodo actual con el padre de este
				
				_item=NULL; //Borramos el ítem el nodo actual
				
				//Desenlazamos y borramos el nodo actual
				auxiliar=this;
				auxiliar->setParent(NULL);
				auxiliar->setRightTree(NULL);
			
				delete auxiliar;
				
			}

			else{ //El nodo actual no tiene padre
				*this=*getRightTree(); //Hacemos que el nodo actual sea el hijo
				
				//Desenlazamos el nodo actual
				getParent()->setRightTree(NULL);
				setParent(NULL);
			}
		}

		else{ //El nodo actual tiene hijo izquierdo y hijo derecho
			setItem(getRightTree()->getMinor()); //Asignamos al nodo actual el ítem del descendiente menor de su hijo derecho
			getRightTree()->remove(getRightTree()->getMinor()); //Borramos el ítem del descendiente menor del hijo derecho del nodo actual
		}
	}

	else if(item<getItem()){ //El ítem es menor que el ítem del nodo actual
		getLeftTree()->remove(item); //Borramos el ítem en el subárbol hijo izquierdo
	}

	else{ //El ítem es mayor que el ítem del nodo actual
		getRightTree()->remove(item); //Borramos el ítem en el subárbol hijo derecho
	}

	//Postcondición
	#ifndef NDEBUG
		assert(!exists(e));
	#endif
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x50, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movq %rsp, %r15
movq %r15, %rdi
callq 0x344a
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2cfc
testb %al, %al
je 0x32fc
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
movq %r14, %rdi
movq %rax, %rsi
callq 0x29a0
testb %al, %al
je 0x317e
movq 0x10(%rbx), %rax
testq %rax, %rax
je 0x31a9
cmpq $0x0, 0x18(%rbx)
je 0x3221
testq %rax, %rax
jne 0x31f0
jmp 0x31b9
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
movq %r14, %rdi
movq %rax, %rsi
callq 0x2a28
xorb $0x1, %al
movzbl %al, %eax
movq 0x10(%rbx,%rax,8), %rdi
movq %r14, %rsi
callq 0x311e
jmp 0x32db
cmpq $0x0, 0x18(%rbx)
je 0x3260
testq %rax, %rax
jne 0x316c
movq 0x18(%rbx), %rcx
testq %rcx, %rcx
je 0x31f0
movq 0x20(%rbx), %rdx
testq %rdx, %rdx
je 0x32ae
leaq 0x18(%rbx), %rax
xorl %esi, %esi
cmpq %rbx, 0x10(%rdx)
setne %sil
movq %rcx, 0x10(%rdx,%rsi,8)
movq 0x18(%rbx), %rcx
movq %rdx, 0x20(%rcx)
leaq 0x8(%rbx), %r14
jmp 0x3248
movq 0x18(%rbx), %rdi
callq 0x2e4c
movq (%rbx), %rcx
movq %rbx, %rdi
movq %rax, %rsi
callq *0x18(%rcx)
movq 0x18(%rbx), %r14
movq %r14, %rdi
callq 0x2e4c
movq %r14, %rdi
movq %rax, %rsi
callq 0x311e
jmp 0x32db
leaq 0x20(%rbx), %r14
movq 0x20(%rbx), %rcx
testq %rcx, %rcx
je 0x3290
xorl %edx, %edx
cmpq %rbx, 0x10(%rcx)
setne %dl
movq %rax, 0x10(%rcx,%rdx,8)
movq 0x10(%rbx), %rax
movq %rcx, 0x20(%rax)
leaq 0x8(%rbx), %rax
movq $0x0, (%r14)
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x8(%rax)
jmp 0x32db
movq 0x20(%rbx), %rax
testq %rax, %rax
je 0x32d0
xorl %ecx, %ecx
cmpq %rbx, 0x10(%rax)
setne %cl
movq $0x0, 0x10(%rax,%rcx,8)
leaq 0x8(%rbx), %r14
movq 0x8(%rbx), %rdi
testq %rdi, %rdi
je 0x32d4
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0x32d4
movups 0x8(%rax), %xmm0
movups 0x18(%rax), %xmm1
movups %xmm1, 0x18(%rbx)
movups %xmm0, 0x8(%rbx)
movq 0x20(%rbx), %rax
movq $0x0, 0x10(%rax)
jmp 0x32d4
leaq 0x20(%rbx), %r14
movups 0x8(%rcx), %xmm0
movups 0x18(%rcx), %xmm1
movups %xmm1, 0x18(%rbx)
movups %xmm0, 0x8(%rbx)
movq 0x20(%rbx), %rax
movq $0x0, 0x18(%rax)
jmp 0x32d4
leaq 0x8(%rbx), %r14
movq $0x0, (%r14)
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x2cfc
testb %al, %al
jne 0x331b
movq %rsp, %rdi
callq 0x3518
addq $0x50, %rsp
popq %rbx
popq %r14
popq %r15
retq
leaq 0x6082(%rip), %rdi      # 0x9385
leaq 0x5e2b(%rip), %rsi      # 0x9135
leaq 0x6027(%rip), %rcx      # 0x9338
movl $0xf4, %edx
callq 0x20f0
leaq 0x6062(%rip), %rdi      # 0x9384
leaq 0x5e0c(%rip), %rsi      # 0x9135
leaq 0x6008(%rip), %rcx      # 0x9338
movl $0x15f, %edx            # imm = 0x15F
callq 0x20f0
jmp 0x333c
movq %rax, %rbx
movq %rsp, %rdi
callq 0x3518
movq %rbx, %rdi
callq 0x2230
movq %rax, %rdi
callq 0x362e
nop