// File: 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 %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x60(%rbp), %rdi
movq %rdi, -0x88(%rbp)
callq 0x41c0
movq -0x90(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x2e80
movb %al, -0x79(%rbp)
jmp 0x35ba
movb -0x79(%rbp), %al
testb $0x1, %al
jne 0x35c3
jmp 0x35c5
jmp 0x35fe
leaq 0x6dff(%rip), %rdi      # 0xa3cb
leaq 0x6b6a(%rip), %rsi      # 0xa13d
movl $0xf4, %edx
leaq 0x6d9f(%rip), %rcx      # 0xa37e
callq 0x2140
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x43d0
jmp 0x3d81
movq -0x90(%rbp), %rdi
movq -0x10(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, -0x98(%rbp)
jmp 0x3622
movq -0x98(%rbp), %rsi
movq -0xa0(%rbp), %rdi
callq 0x2960
movb %al, -0xa1(%rbp)
jmp 0x363d
movb -0xa1(%rbp), %al
testb $0x1, %al
jne 0x364c
jmp 0x3c89
movq -0x90(%rbp), %rdi
callq 0x3f10
movb %al, -0xa2(%rbp)
jmp 0x3660
movb -0xa2(%rbp), %al
testb $0x1, %al
jne 0x3797
jmp 0x3670
movq -0x90(%rbp), %rdi
callq 0x3f60
movb %al, -0xa3(%rbp)
jmp 0x3684
movb -0xa3(%rbp), %al
testb $0x1, %al
jne 0x3797
jmp 0x3694
movq -0x90(%rbp), %rdi
callq 0x4330
movb %al, -0xa4(%rbp)
jmp 0x36a8
movb -0xa4(%rbp), %al
testb $0x1, %al
jne 0x36b7
jmp 0x3783
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0xb0(%rbp)
jmp 0x36cc
movq -0xb0(%rbp), %rdi
callq 0x3f40
movq %rax, -0xb8(%rbp)
jmp 0x36e1
movq -0xb8(%rbp), %rax
movq -0x90(%rbp), %rcx
cmpq %rcx, %rax
jne 0x371d
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0xc0(%rbp)
jmp 0x3709
movq -0xc0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3fb0
jmp 0x371b
jmp 0x3746
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0xc8(%rbp)
jmp 0x3732
movq -0xc8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4000
jmp 0x3744
jmp 0x3746
movq -0x90(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xd0(%rbp)
cmpq $0x0, %rax
je 0x3772
movq -0xd0(%rbp), %rdi
movq (%rdi), %rax
movq 0x8(%rax), %rax
callq *%rax
jmp 0x3770
jmp 0x3772
movq -0x90(%rbp), %rax
movq $0x0, 0x8(%rax)
jmp 0x3792
movq -0x90(%rbp), %rax
movq $0x0, 0x8(%rax)
jmp 0x3c84
movq -0x90(%rbp), %rdi
callq 0x3f10
movb %al, -0xd1(%rbp)
jmp 0x37ab
movb -0xd1(%rbp), %al
testb $0x1, %al
jne 0x37ba
jmp 0x39bf
movq -0x90(%rbp), %rdi
callq 0x3f60
movb %al, -0xd2(%rbp)
jmp 0x37ce
movb -0xd2(%rbp), %al
testb $0x1, %al
jne 0x39bf
jmp 0x37de
movq -0x90(%rbp), %rdi
callq 0x4330
movb %al, -0xd3(%rbp)
jmp 0x37f2
movb -0xd3(%rbp), %al
testb $0x1, %al
jne 0x3801
jmp 0x3957
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0xe0(%rbp)
jmp 0x3816
movq -0xe0(%rbp), %rdi
callq 0x3f40
movq %rax, -0xe8(%rbp)
jmp 0x382b
movq -0xe8(%rbp), %rax
movq -0x90(%rbp), %rcx
cmpq %rcx, %rax
jne 0x387f
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0xf0(%rbp)
jmp 0x3853
movq -0x90(%rbp), %rdi
callq 0x3f40
movq %rax, -0xf8(%rbp)
jmp 0x3868
movq -0xf8(%rbp), %rsi
movq -0xf0(%rbp), %rdi
callq 0x3fb0
jmp 0x387d
jmp 0x38c0
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0x100(%rbp)
jmp 0x3894
movq -0x90(%rbp), %rdi
callq 0x3f40
movq %rax, -0x108(%rbp)
jmp 0x38a9
movq -0x108(%rbp), %rsi
movq -0x100(%rbp), %rdi
callq 0x4000
jmp 0x38be
jmp 0x38c0
movq -0x90(%rbp), %rdi
callq 0x3f40
movq %rax, -0x110(%rbp)
jmp 0x38d5
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0x118(%rbp)
jmp 0x38ea
movq -0x118(%rbp), %rsi
movq -0x110(%rbp), %rdi
callq 0x4050
jmp 0x38ff
movq -0x90(%rbp), %rax
movq $0x0, 0x8(%rax)
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4050
jmp 0x3921
movq -0x78(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3fb0
jmp 0x3930
movq -0x78(%rbp), %rax
movq %rax, -0x120(%rbp)
cmpq $0x0, %rax
je 0x3955
movq -0x120(%rbp), %rdi
movq (%rdi), %rax
movq 0x8(%rax), %rax
callq *%rax
jmp 0x3953
jmp 0x3955
jmp 0x39ba
movq -0x90(%rbp), %rdi
callq 0x3f40
movq %rax, -0x128(%rbp)
jmp 0x396c
movq -0x90(%rbp), %rdi
movq -0x128(%rbp), %rsi
callq 0x4380
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0x130(%rbp)
jmp 0x3994
movq -0x130(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3fb0
jmp 0x39a6
movq -0x90(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4050
jmp 0x39b8
jmp 0x39ba
jmp 0x3c82
movq -0x90(%rbp), %rdi
callq 0x3f10
movb %al, -0x131(%rbp)
jmp 0x39d3
movb -0x131(%rbp), %al
testb $0x1, %al
jne 0x3be7
jmp 0x39e3
movq -0x90(%rbp), %rdi
callq 0x3f60
movb %al, -0x132(%rbp)
jmp 0x39f7
movb -0x132(%rbp), %al
testb $0x1, %al
jne 0x3a06
jmp 0x3be7
movq -0x90(%rbp), %rdi
callq 0x4330
movb %al, -0x133(%rbp)
jmp 0x3a1a
movb -0x133(%rbp), %al
testb $0x1, %al
jne 0x3a29
jmp 0x3b7f
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0x140(%rbp)
jmp 0x3a3e
movq -0x140(%rbp), %rdi
callq 0x3f40
movq %rax, -0x148(%rbp)
jmp 0x3a53
movq -0x148(%rbp), %rax
movq -0x90(%rbp), %rcx
cmpq %rcx, %rax
jne 0x3aa7
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0x150(%rbp)
jmp 0x3a7b
movq -0x90(%rbp), %rdi
callq 0x3f90
movq %rax, -0x158(%rbp)
jmp 0x3a90
movq -0x158(%rbp), %rsi
movq -0x150(%rbp), %rdi
callq 0x3fb0
jmp 0x3aa5
jmp 0x3ae8
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0x160(%rbp)
jmp 0x3abc
movq -0x90(%rbp), %rdi
callq 0x3f90
movq %rax, -0x168(%rbp)
jmp 0x3ad1
movq -0x168(%rbp), %rsi
movq -0x160(%rbp), %rdi
callq 0x4000
jmp 0x3ae6
jmp 0x3ae8
movq -0x90(%rbp), %rdi
callq 0x3f90
movq %rax, -0x170(%rbp)
jmp 0x3afd
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0x178(%rbp)
jmp 0x3b12
movq -0x178(%rbp), %rsi
movq -0x170(%rbp), %rdi
callq 0x4050
jmp 0x3b27
movq -0x90(%rbp), %rax
movq $0x0, 0x8(%rax)
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4050
jmp 0x3b49
movq -0x78(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4000
jmp 0x3b58
movq -0x78(%rbp), %rax
movq %rax, -0x180(%rbp)
cmpq $0x0, %rax
je 0x3b7d
movq -0x180(%rbp), %rdi
movq (%rdi), %rax
movq 0x8(%rax), %rax
callq *%rax
jmp 0x3b7b
jmp 0x3b7d
jmp 0x3be2
movq -0x90(%rbp), %rdi
callq 0x3f90
movq %rax, -0x188(%rbp)
jmp 0x3b94
movq -0x90(%rbp), %rdi
movq -0x188(%rbp), %rsi
callq 0x4380
movq -0x90(%rbp), %rdi
callq 0x4360
movq %rax, -0x190(%rbp)
jmp 0x3bbc
movq -0x190(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4000
jmp 0x3bce
movq -0x90(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4050
jmp 0x3be0
jmp 0x3be2
jmp 0x3c80
movq -0x90(%rbp), %rdi
callq 0x3f90
movq %rax, -0x198(%rbp)
jmp 0x3bfc
movq -0x198(%rbp), %rdi
callq 0x31b0
movq %rax, -0x1a0(%rbp)
jmp 0x3c11
movq -0x1a0(%rbp), %rsi
movq -0x90(%rbp), %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
jmp 0x3c2a
movq -0x90(%rbp), %rdi
callq 0x3f90
movq %rax, -0x1a8(%rbp)
jmp 0x3c3f
movq -0x90(%rbp), %rdi
callq 0x3f90
movq %rax, -0x1b0(%rbp)
jmp 0x3c54
movq -0x1b0(%rbp), %rdi
callq 0x31b0
movq %rax, -0x1b8(%rbp)
jmp 0x3c69
movq -0x1b8(%rbp), %rsi
movq -0x1a8(%rbp), %rdi
callq 0x3570
jmp 0x3c7e
jmp 0x3c80
jmp 0x3c82
jmp 0x3c84
jmp 0x3d28
movq -0x90(%rbp), %rdi
movq -0x10(%rbp), %rax
movq %rax, -0x1c8(%rbp)
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, -0x1c0(%rbp)
jmp 0x3cad
movq -0x1c0(%rbp), %rsi
movq -0x1c8(%rbp), %rdi
callq 0x29e0
movb %al, -0x1c9(%rbp)
jmp 0x3cc8
movb -0x1c9(%rbp), %al
testb $0x1, %al
jne 0x3cd4
jmp 0x3cfd
movq -0x90(%rbp), %rdi
callq 0x3f40
movq %rax, -0x1d8(%rbp)
jmp 0x3ce9
movq -0x1d8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x3570
jmp 0x3cfb
jmp 0x3d26
movq -0x90(%rbp), %rdi
callq 0x3f90
movq %rax, -0x1e0(%rbp)
jmp 0x3d12
movq -0x1e0(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x3570
jmp 0x3d24
jmp 0x3d26
jmp 0x3d28
movq -0x90(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x2e80
movb %al, -0x1e1(%rbp)
jmp 0x3d40
movb -0x1e1(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x3d4e
jmp 0x3d50
jmp 0x3d6f
leaq 0x6673(%rip), %rdi      # 0xa3ca
leaq 0x63df(%rip), %rsi      # 0xa13d
movl $0x15f, %edx            # imm = 0x15F
leaq 0x6614(%rip), %rcx      # 0xa37e
callq 0x2140
leaq -0x60(%rbp), %rdi
callq 0x43d0
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
jmp 0x3d83
movq -0x68(%rbp), %rdi
callq 0x22b0
movq %rax, %rdi
callq 0x45c0
nopw %cs:(%rax,%rax)