Tengo un problemo con esto, el programa me lo pasaron implementado en turbo C. Lo modifique para mi uso. Pero me da error al ejecutar (Error de aplicacion, la instruccion en "0x00402032" hace referencia a la memoria en "0x00310033", la memoria no se puede written), le he hecho comentarios para rastrearlo y es en el mensaje entra a empujar3 no se que hacer:ahcanijo:
la diferencia entre los 2 es que yo utilizo un fichero csv para llenar el árbol, pero no empieza por que se queda en el mensaje que mencione.
He utilizado en NetBeans y el wxDev-C++ para compilar y ejecutar. Siempre me sale el error (Error de aplicacion, la instruccion en "0x00402032" hace referencia a la memoria en "0x00310033", la memoria no se puede written)
Espero sus respuestas
bdprn2015.csv
MI CODIGO
el que me pasaron:
la diferencia entre los 2 es que yo utilizo un fichero csv para llenar el árbol, pero no empieza por que se queda en el mensaje que mencione.
He utilizado en NetBeans y el wxDev-C++ para compilar y ejecutar. Siempre me sale el error (Error de aplicacion, la instruccion en "0x00402032" hace referencia a la memoria en "0x00310033", la memoria no se puede written)
Espero sus respuestas
bdprn2015.csv
Código:
Brayan Anthony,Herrera Calderon,hc08042,hc08042@ues.edu.sv,2,5.6,7.8,9,10,7,0
Oscar Roberto,Gutiérrez Fonseca,gf10012,gf10012@ues.edu.sv,1,0,0,0,0,0,0
Irving Vladimir,Oliva Avelar,oa09020,oa09020@ues.edu.sv,1,0,0,0,0,0,0
Carlos Alberto,Lopez Chorro,lc06008,lc06008@ues.edu.sv,1,0,0,0,0,0,0
Mario Fidel,Zavala Hernandez,zh09001,zh09001@ues.edu.sv,1,0,0,0,0,0,0
Luis Ernesto,Morales Campos,mc11004,mc11004@ues.edu.sv,1,0,0,0,0,0,0
Roxana Elizabeth,Castillo Aquino,ca11001,ca11001@ues.edu.sv,1,0,0,0,0,0,0
Irma Mercedes,Pineda Laínez,pl10009,pl10009@ues.edu.sv,1,0,0,0,0,0,0
Beatriz Del Carmen,Panameño Merino,pm11071,pm11071@ues.edu.sv,1,0,0,0,0,0,0
Jose Heriberto,Campos Nerio,cn08010,cn08010@ues.edu.sv,1,0,0,0,0,0,0
Willson Arnoldo,Funes Colorado,fc08026,fc08026@ues.edu.sv,1,0,0,0,0,0,0
Código:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include <cstdlib>
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <fstream>
using namespace std;
#define F2 60
#define UP 72
#define DOWN 80
#define INTRO 13
typedef int tipoclave;
typedef struct date
{
char nombres[25], apellidos[25], due[8], correo[19];
float notas[6];
int matricula;
tipoclave correlativo;
}datep;
typedef datep *prtdatep;
typedef struct tnodo
{
tipoclave tclave;
prtdatep direc;
}lnodo;
typedef lnodo *plnodo;
/*-------------------------------------------------------------*/
/* Estructura del Arbol B */
/*-------------------------------------------------------------*/
#define m 5 //Orden del Arbol B - Como maximo: m ramas - Y m-1 Claves
typedef struct pagina
{
lnodo claves[m]; //m{0..9} Numero de claves sera for(k=1;k<=m;k++)
struct pagina *ramas[m];
int cuenta; //Numero de claves de la pagina
}pag;
typedef pag *tpagina;
/*-------------------------------------------------------------*/
/* Declaracion de funciones a utilizar */
/*-------------------------------------------------------------*/
prtdatep getnode(void); //creacion del nodo q almacenara la informacion del alumno
void creararbolB(tpagina *);
void llenarrg(prtdatep registro); //funcion que llena el registro del alumno
int nodolleno(tpagina actual);
int nodosemivacio(tpagina actual);
int buscarnodo(tpagina actual,tipoclave clbuscar,int *k);
int buscarnodoinsert(tpagina actual,prtdatep info,int *k);
void insertar(tpagina *raiz,prtdatep info);
void empujar(tpagina actual,prtdatep info,int *,plnodo *,tpagina *);
void eliminar(tpagina *,tipoclave d);
void eliminarregistro(tpagina actual,tipoclave cl,int *encontrado);
void dividirnodo(tpagina actual,plnodo cl,tpagina rd,int k,plnodo *,tpagina *);
void meterhoja(tpagina actual,plnodo cl,tpagina rd,int k);
void quitar(tpagina actual,int k);
void sucesor(tpagina actual,int k);
void restablecer(tpagina actual,int k);
void moverderecha(tpagina actual,int k);
void moverizquierda(tpagina actual,int k);
void combina(tpagina actual,int k);
void splash();
tpagina buscar(tpagina actual,tipoclave cl,int *);
tpagina buscar_due(tpagina actual,char *,int *);
void start(tpagina *);
int menu(char (*text)[30], int max)//recibe un arrego de cadenas buffer maximo asignado 30(longitud)
{
int key, op=0, i;//key registra la tecla presionada
while(key!=INTRO)
{
system("CLS");
for(i=0;i<max;i++)
{
if(op==i)//imprime flecha si arreglo y op son iguales
cout << " =>";
cout << "\t"<< (i+1) <<") "<< text[i] << endl;
}
do{
key=getch();
}while(key!=UP&&key!=DOWN&&key!=INTRO);
switch(key)
{
case UP:
if(op==0)
op=max-1;
else
op--;
break;
case DOWN:
if(op==max-1)
op=0;
else
op++;
break;
}
}
op+=1;
return op; //retorna la opcion +1
}
int main()
{
char text[5][30]={{"Introducir un registro"},{"Eliminar un registro"},{"Buscar y Mostrar un registro"},{"Modificar un registro"},{"Salir de la Aplicacion"}};
char due[8];
int i,op=0,salir=6,nm,cancelar,posicion;
tipoclave d;
prtdatep info,direcbus;
tpagina arbol;
tpagina bus;
system("cls");
splash();
creararbolB(&arbol);
start(&arbol);
while(op!=5)
{
system("cls");
fflush(stdin);
switch(op=menu(text,5))
{
case 1:
{
fflush(stdin);
info=getnode();
llenarrg(info);
insertar(&arbol,info);
}
break;
case 2:
{
fflush(stdin);
system("cls");
puts("\n\nELIMINACION DE REGISTRO");
printf("\n\nUsted a elejido la opcion de eliminar un registro\n\n Digite el ID:\n ");
scanf("%d",&d);
eliminar(&arbol,d);
}
break;
case 3:
{
fflush(stdin);
system("cls");
puts("\n\n°°°°°°°°°° BUSQUEDA DE UN REGISTRO °°°°°°°°°°");
printf("\n\n Digite el ID de alumno para mostrar toda su informacion si no lo conoce digite -1 para buscarlo por el DUE:\n ");
scanf("%d",&d);
/* if(d==-1){
printf("\n\n Digite el due del alumno:\n ");
gets(d);
bus=buscar_due(arbol,d,&posicion);}
else */bus=buscar(arbol,d,&posicion);
if(bus==NULL)
{
puts("\n\nACTUALMENTE NO SE ENCUENTRA NINGUN REGISTRO");
getch();
}
else
{
for(i=0;i<=bus->cuenta;i++)
{
fflush(stdin);
if(bus->claves[i].tclave==d)
{
direcbus=bus->claves[i].direc;
system("cls");
puts("\n\n°°°°°°°°°° RESULTADOS DE LA BUSQUEDA°°°°°°°°°°");
printf("\nID: %d",d);
printf("\n\nNombres: %s",direcbus->nombres);
printf("\n\nApellidos: %s",direcbus->apellidos);
printf("\ndue: %s",direcbus->due);
printf("\nCorreo: %s",direcbus->correo);
printf("\nPar 1\tPar 2\tPar 3\tLab\tTE\tFINAL");
printf("\n%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f",direcbus->notas[0],direcbus->notas[1],direcbus->notas[2],direcbus->notas[3],direcbus->notas[4],direcbus->notas[5]);
getch();
}
}
}
}
break;
case 4:
{
fflush(stdin);
system("cls");
puts("\n\n°°°°°°°°°° MODIFICACION DE UN REGISTRO °°°°°°°°°°");
puts(" °°°°°°°°°° DE TRABAJADOR °°°°°°°°°°");
printf("\n\n Digite el DUE para mostrar toda su informacion:\n ");
fflush(stdin);
gets(due);//scanf("%d",&d);
bus=buscar(arbol,d,&posicion);
if(bus==NULL)
{
puts("\n\nACTUALMENTE NO SE ENCUENTRA NINGUN REGISTRO");
getch();
}
else
{
for(i=0;i<=bus->cuenta;i++)
{
if(bus->claves[i].tclave==d)
{
direcbus=bus->claves[i].direc;
system("cls");
puts("\n\nRESULTADOS DE LA BUSQUEDA");
printf("\nID: %d",d);
printf("\n\nNombres: %s",direcbus->nombres);
printf("\n\nApellidos: %s",direcbus->apellidos);
printf("\ndue: %s",direcbus->due);
printf("\nCorreo: %s",direcbus->correo);
printf("\nPar 1\tPar 2\tPar 3\tLab\tTE\tFINAL");
printf("\n%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f",direcbus->notas[0],direcbus->notas[1],direcbus->notas[2],direcbus->notas[3],direcbus->notas[4],direcbus->notas[5]);
getch();
puts("\n\n¨ Realmente quiere modificarlo ?\n");
puts("Digite: 1 o 2\n1 -> Si, deseo modificarlo\n2 -> No, asi esta bien");
scanf("%d",&nm);
if(nm==1)
{
fflush(stdin);
llenarrg(direcbus);
bus->claves[i].tclave=direcbus->correlativo;
}
else
{
puts("\n Presione cualquier tecla para volver al menu principal");
getch();
}
}
}
}
}
break;
case 5:
{
fflush(stdin);
system("cls");
printf("\nDesea realmente salir de la aplicacion: ");
printf("\nDIGITE>\n1-aceptar\n2-cancelar: ");
scanf("%d",&cancelar);
while(cancelar<1||cancelar>2)
{
system("cls");
puts("\nERROR!!!... debe de digitar una operacion valida");
printf("\nDigite 1-aceptar 2-cancelar: ");
scanf("%d",&cancelar);
}
if(cancelar==1)
salir=0;
else
{
system("cls");
puts("\nPresione enter para regresar al menu...");
getch();
}
}
break;
}
}
}
void creararbolB(tpagina *raiz)
{
*raiz=NULL;
}
prtdatep getnode(void)
{
prtdatep newnodo;
newnodo=(prtdatep)malloc(sizeof(date));
if(newnodo==NULL)
{
puts("\nError sin espacio en memoria...");
exit(1);
}
return newnodo;
}
void llenarrg(prtdatep registro)
{
char temp[25];int mat;
float dato;
tipoclave corr;
char dept[40];
char dir[100];
system("cls");
puts("\n\nINFORMACION PERSONAL");
puts("DEL ESTUDIANTE");
puts("\n\nDigite la Informacion Solicitada");
printf("\n\n\nNombres: ");
gets(temp);
strcpy(registro->nombres,temp);
printf("\n\n\nApellidos: ");
gets(temp);
strcpy(registro->apellidos,temp);
printf("\ndue: ");
gets(temp);
strcpy(registro->due,temp);
strcat(temp,"@ues.edu.sv");
strcpy(registro->correo,temp);
printf("\nDigite la matricula de la materia inscrita: ");
scanf("%d",&mat);
registro->matricula=mat;
printf("\nDigite la nota del parcial 1: ");
scanf("%f",&dato);
registro->notas[0]=dato;
printf("\nDigite la nota del parcial 2: ");
scanf("%f",&dato);
registro->notas[1]=dato;
printf("\nDigite la nota del parcial 3: ");
scanf("%f",&dato);
registro->notas[2]=dato;
printf("\nDigite la nota del laboratorio: ");
scanf("%f",&dato);
registro->notas[3]=dato;
printf("\nDigite la nota de la tarea exaula: ");
scanf("%f",&dato);
registro->notas[4]=dato;
registro->notas[5]=((registro->notas[0])*0.15)+(((registro->notas[1])+(registro->notas[2])+(registro->notas[4]))*0.2)+((registro->notas[5])*0.25);
printf("\nID unico: ");
scanf("%d",&corr);
registro->correlativo=corr;
fflush(stdin);
}
int nodolleno(tpagina actual) //revisa si la pagina esta llena
{
return(actual->cuenta==m-1);
}
int nodosemivacio(tpagina actual) //revisa si la pagina esta semivacio
{
return(actual->cuenta<m/2);
}
int buscarnodoinsert(tpagina actual,prtdatep info,int *k)
{ cout<<"entra a buscarnodoinsert";
int encontrado; //k indica la posicion dentro de las claves
if((info->correlativo)<(actual->claves[1].tclave)) //la clave es menor que la clave de esta pagina
{ cout<<"entra a buscarnodoinsert2";
encontrado=0;
*k=0; //indica que debe seguir por el ptr a la pagina con las claves mas chicas
}
else //examinan las claves del nodo en orden descendete
{ cout<<"entra a buscarnodoinsert3";
*k=actual->cuenta;
while((info->correlativo<actual->claves[*k].tclave)&&(*k>1))
(*k)--;
encontrado=(info->correlativo==actual->claves[*k].tclave);
}
return encontrado;
}
void insertar(tpagina *raiz,prtdatep info)
{ cout<<"entra a arbol";
int subearriba;
plnodo mediana;
tpagina p,nd;
empujar(*raiz,info,&subearriba,&mediana,&nd);
if(subearriba) //crece de nivel por la raiz, si la propagacion llega a la cima
{
p=(tpagina)malloc(sizeof(pagina));
p->cuenta=1;
p->claves[1].tclave=mediana->tclave;
p->claves[1].direc=mediana->direc;
p->ramas[0]=*raiz;
p->ramas[1]=nd;
*raiz=p;
}
}
void empujar(tpagina actual,prtdatep info,int *subearriba,plnodo *mediana,tpagina *nuevo)
{ cout<<"entra a empujar";
int k; //posicion dentro del espacio de claves de pagina
int esta;cout<<"entra a empujar2";
if(actual==NULL)
{ cout<<"entra a empujar3";
*subearriba=1;
(*mediana)->tclave=info->correlativo;
(*mediana)->direc=info;
*nuevo=NULL;
}
else
{ cout<<"entra a empujar4";
esta=buscarnodoinsert(actual,info,&k); //Baja hasta una rama vacia
if(esta)
{
puts("\nClave Duplicada");
getch();
*subearriba=0;
return;
}
empujar(actual->ramas[k],info,subearriba,mediana,nuevo);
//La recursion devuelve el contro; vuelve por el camino de busqueda
if(*subearriba) //sera 1 cuando su rama=null => inserta pues no podemos seguir bajando
{ cout<<"entra a empujar5";
if(nodolleno(actual))
dividirnodo(actual,*mediana,*nuevo,k,mediana,nuevo);
else
{ cout<<"entra a empujar6";
*subearriba=0;
meterhoja(actual,*mediana,*nuevo,k);
}
} //dejara de elevar medianas cuando pueda almenos una vez meterhoja
}
cout<<"termina empujar";
}
void meterhoja(tpagina actual,plnodo cl,tpagina rd,int k)
{
int i;
/*Desplaza a la derecha los elementos para hacer un hueco*/
for(i=actual->cuenta;i>=k+1;i--)
{
actual->claves[i+1].tclave=actual->claves[i].tclave;
actual->ramas[i+1]=actual->ramas[i];
}
actual->claves[k+1].tclave=cl->tclave;
actual->claves[k+1].direc=cl->direc;
actual->ramas[i+1]=rd;
actual->cuenta++;
}
void dividirnodo(tpagina actual,plnodo cl,tpagina rd,int k,plnodo *mediana,tpagina *nuevo)
{
int i,posmdna;
posmdna=(k<=m/2)? m/2: m/2+1; //posicion de clave mediana
(*nuevo)=(tpagina)malloc(sizeof(pagina)); //nuevo nodo
for(i=posmdna+1;i<m;i++)
{ //Es desplazada la mitad derecha al nuevo nodo la clave mediana se queda en el nodo origen
(*nuevo)->claves[i-posmdna].tclave=actual->claves[i].tclave;
(*nuevo)->ramas[i-posmdna]=actual->ramas[i];
}
(*nuevo)->cuenta=(m-1)-posmdna; //clave en el nuevo nodo
actual->cuenta=posmdna; //clave en el nodo hijo
//es insertada la clave y rama en el nodo que le corresponde
if(k>=m/2)
meterhoja(actual,cl,rd,k); //inserta el nodo origen
else
meterhoja(*nuevo,cl,rd,k-posmdna);
//se extrae la clave mediana del nodo origen
(*mediana)->tclave=actual->claves[actual->cuenta].tclave;
(*mediana)->direc=actual->claves[actual->cuenta].direc;
//rama del nuevo nodo es la rama de la mediana
(*nuevo)->ramas[0]=actual->ramas[actual->cuenta];
actual->cuenta--; //disminuye ya que se quita la mediana
}
void eliminar(tpagina *raiz,tipoclave d)
{
int encontrado;
eliminarregistro(*raiz,d,&encontrado);
if(encontrado)
{
printf("La eliminacion del registro se realizo existosamente");
getch();
if((*raiz)->cuenta==0)
{ /* La raiz esta vacia, libera el nodo y se establece la nueva raiz */
tpagina p = *raiz;
*raiz = (*raiz)->ramas[0];
free(p);
}
}
else
{
puts("El registro de esta persona no se encuentra\n");
getch();
}
}
void eliminarregistro(tpagina actual,tipoclave cl,int *encontrado)
{
int k;
if(actual!=NULL)
{
*encontrado = buscarnodo(actual,cl,&k); /* Busca la hoja con el DUI */
if(*encontrado)
{
if(actual->ramas[k-1] == NULL)/* Pregunta si es actual un nodo hoja */
quitar(actual,k);/* Quita la clave de la hoja en nuestro caso el correlativo y todo el registro */
else
{
sucesor(actual,k);/* Encuentra la clave sucesora y hace el intercambio */
eliminarregistro(actual->ramas[k],actual->claves[k].tclave,encontrado); /* Como va con la
pagina descendente, buscara hasta encontrar la pagina hoja con el que dato sucesor(que ya se cambio) y lo quitara */
}
}
else eliminarregistro(actual->ramas[k],cl,encontrado);
if(actual->ramas[k] != NULL)
if(actual->ramas[k]->cuenta < (m/2))
restablecer(actual,k);
}
else *encontrado = 0;
}
void quitar(tpagina actual,int k)
{
int j;
for(j=k+1;j<=actual->cuenta;j++)
{
actual->claves[j-1].tclave=actual->claves[j].tclave;
actual->claves[j-1].direc=actual->claves[j].direc;
actual->ramas[j-1]=actual->ramas[j];
}
actual->cuenta--;
}
void sucesor(tpagina actual,int k)
{
tpagina q;
q=actual->ramas[k];
while(q->ramas[0]!=NULL)
q=q->ramas[0]; //q referencia al nodo hoja
actual->claves[k].tclave=q->claves[1].tclave;
actual->claves[k].direc=q->claves[1].direc;
}
void restablecer(tpagina actual,int k)
{
//actual tiene la direccion del nodo antecedente de actual->ramas[k] que tiene menos claves que el minimo
if(k>0) //tiene hermano izquierdo
if(actual->ramas[k-1]->cuenta > m/2)
moverderecha(actual,k);
else
combina(actual,k);
else //solo tiene mano derecho
if(actual->ramas[1]->cuenta > m/2)
moverizquierda(actual,1);
else
combina(actual,1);
}
int buscarnodo(tpagina actual,tipoclave clbuscar,int *k)
{
int encontrado; //k indica la posicion dentro de las claves
if(clbuscar<actual->claves[1].tclave) //la clave es menor que la clave de esta pagina
{
encontrado=0;
*k=0; //indica que debe seguir por el ptr a la pagina con las claves mas chicas
}
else //examinan las claves del nodo en orden descendete
{
*k=actual->cuenta;
while((clbuscar<actual->claves[*k].tclave)&&(*k>1))
(*k)--;
encontrado=(clbuscar==actual->claves[*k].tclave);
}
return encontrado;
}
void moverderecha(tpagina actual,int k)
{
int j;
tpagina nodoproblema=actual->ramas[k];
tpagina nodoizqdo=actual->ramas[k-1];
for(j=nodoproblema->cuenta;j>=1;j--)
{
nodoproblema->claves[j+1].tclave=nodoproblema->claves[j].tclave;
nodoproblema->claves[j+1].direc=nodoproblema->claves[j].direc;
nodoproblema->ramas[j+1]=nodoproblema->ramas[j];
}
nodoproblema->cuenta++;
nodoproblema->ramas[1]=nodoproblema->ramas[0];
//baja la clave del nodo padre
nodoproblema->claves[1].tclave=actual->claves[k].tclave;
nodoproblema->claves[1].direc=actual->claves[k].direc;
//sube la clave del hermano izquierdo al nodo clave para reemplazar la que antes bajo
actual->claves[k].tclave=nodoizqdo->claves[nodoizqdo->cuenta].tclave;
actual->claves[k].direc=nodoizqdo->claves[nodoizqdo->cuenta].direc;
nodoproblema->ramas[0]=nodoizqdo->ramas[nodoizqdo->cuenta];
nodoizqdo->cuenta--;
}
void moverizquierda(tpagina actual,int k)
{
int j;
tpagina nodoproblema=actual->ramas[k-1];
tpagina nododrcho=actual->ramas[k];
nodoproblema->cuenta++;
nodoproblema->claves[nodoproblema->cuenta].tclave=actual->claves[k].tclave;
nodoproblema->claves[nodoproblema->cuenta].direc=actual->claves[k].direc;
nodoproblema->ramas[nodoproblema->cuenta]=nododrcho->ramas[0];
actual->claves[k].tclave=nododrcho->claves[1].tclave;
actual->claves[k].direc=nododrcho->claves[1].direc;
nododrcho->ramas[1]=nododrcho->ramas[0];
nododrcho->cuenta--;
for(j=1;j<=nododrcho->cuenta;j++)
{
nododrcho->claves[j].tclave=nododrcho->claves[j+1].tclave;
nododrcho->claves[j].direc=nododrcho->claves[j+1].direc;
nododrcho->ramas[j]=nododrcho->ramas[j+1];
}
}
void combina(tpagina actual,int k)
{
int j;
tpagina nodoizqdo, q;
q=actual->ramas[k];
nodoizqdo=actual->ramas[k-1];
//"baja" clave mediana desde el nodo padre
nodoizqdo->cuenta++;
nodoizqdo->claves[nodoizqdo->cuenta].tclave=actual->claves[k].tclave;
nodoizqdo->claves[nodoizqdo->cuenta].direc=actual->claves[k].direc;
nodoizqdo->ramas[nodoizqdo->cuenta]=q->ramas[0];
//"mueve" claves del nodo derecho
for(j=1;j<=q->cuenta;j++)
{
actual->claves[j].tclave=actual->claves[j+1].tclave;
actual->claves[j].direc=actual->claves[j+1].direc;
actual->ramas[j]=actual->ramas[j+1];
}
actual->cuenta--;
free(q);
}
tpagina buscar(tpagina actual,tipoclave cl,int *indice)
{
if(actual==NULL)
{
return NULL;
}
else
{
int esta;
esta=buscarnodo(actual,cl,indice);
if(esta)
return actual;
else
return buscar(actual->ramas[*indice],cl,indice);
}
}
/*
tpagina buscar_due(tpagina actual,char *cl,int *indice)
{
if(actual==NULL)
{
return NULL;
}
else
{
int esta;
esta=buscarnodo(actual,cl,indice);
if(esta)
return actual;
else
return buscar(actual->ramas[*indice],cl,indice);
}
}*/
void splash()
{
FILE *archivo;
char cadena[81];
int key;
while(key!=F2)
{
archivo=fopen("splash.txt","r");
system("CLS");
while(fgets(cadena,80,archivo) != NULL)
{
printf("%s",cadena);
}
fclose(archivo);
cout << "\n\nEn espera. Pulse F2 para continuar con el programa";
key=getch();
}
}
void start(tpagina * arbol){
char temp[25], cad[100];
float dato;
int i=0,mat,pos=0,posF=1,j=0,ele=0;
FILE *archivo;
archivo=fopen("bdprn215.csv","r");
cout<<"abriendo archivo"<<endl;
while(fgets(cad,100,archivo) != NULL){
puts(cad);
getch();
i++;
prtdatep registro;
registro=getnode();cout<<"Obteniendo NODO"<<endl;
while(posF!=strlen(cad))
{cout<<pos;
if(*(cad+pos)!=','){cout<<"Leyendo "<<*(cad+pos)<<endl;
if(*(cad+pos)!='\n')
switch(ele){
case 0:registro->nombres[j]=*(cad+pos);break;
case 1:registro->apellidos[j]=*(cad+pos);break;
case 2:registro->due[j]=*(cad+pos);break;
case 3:registro->correo[j]=*(cad+pos);break;
default:temp[j]=*(cad+pos);break;
}
else registro->notas[5]=((registro->notas[0])*0.15)+(((registro->notas[1])+(registro->notas[2])+(registro->notas[4]))*0.2)+((registro->notas[5])*0.25);
j++; pos++;
}
else{cout<<"Entra en el else de ele"<<endl;
switch(ele){
case 4:registro->matricula= atoi(temp);break;
case 5:registro->notas[0]= atof(temp);break;
case 6:registro->notas[1]= atof(temp);break;
case 7:registro->notas[2]= atof(temp);break;
case 8:registro->notas[3]= atof(temp);break;
case 9:registro->notas[4]= atof(temp);break;
}
ele++;j=0;pos++;}
posF++;
}
registro->correlativo=i;
cout<<"insertar"<<endl;
insertar(&(*arbol),registro);
cout<<"insertar 2"<<endl;
ele=0;}
}
Código:
/*--------------------------------------------------------------*/
/* TAREA DE PRN215 Ciclo I 2011 */
/* TEMA: ARBOLES B */
/* GRUPO TEORICO: 01 */
/* */
/*--------------------------------------------------------------*/
/*********************************************»
° PROGRAMA ELABORADO EN COMPILADOR: °
° TURBO C++ °
° VERSION 3.0 °
° BORLAND INTERNATIONAL °
°---------------------------------------------°
° CODIGO FUENTE POR: °
° DENNISS ALEXANDER AYALA SORIANO °
° JIMMY ALEXANDER MENDEZ MARTINEZ °
° GRUPO: 21 °
È**********************************************/
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#include<iostream>
/*-----------------------------------------------------------------*/
/* Estructura del nodo que contendra la informacion del producto */
/*-----------------------------------------------------------------*/
typedef int tipoclave;
typedef struct date
{
char nombre[20];
char codigo[10];
tipoclave cod;
char departamento[40];
char existen[8];
}datep;
typedef datep *prtdatep;
typedef struct tnodo
{
tipoclave tclave;
prtdatep direc;
}lnodo;
typedef lnodo *plnodo;
/*-------------------------------------------------------------*/
/* Estructura del Arbol B */
/*-------------------------------------------------------------*/
#define m 5 //Orden del Arbol B - Como maximo: m ramas - Y m-1 Claves
typedef struct pagina
{
lnodo claves[m]; //m{0..9} Numero de claves sera for(k=1;k<=m;k++)
struct pagina *ramas[m];
int cuenta; //Numero de claves de la pagina
}pag;
typedef pag *tpagina;
/*-------------------------------------------------------------*/
/* Declaracion de funciones a utilizar */
/*-------------------------------------------------------------*/
prtdatep getnode(void); //creacion del nodo q almacenara la informacion del producto
int menu(void); //menu del programa
void creararbolB(tpagina *raiz);
void llenarrg(prtdatep registro); //funcion que llena el registro del producto
int nodolleno(tpagina actual);
int nodosemivacio(tpagina actual);
int buscarnodo(tpagina actual,tipoclave clbuscar,int *k);
int buscarnodoinsert(tpagina actual,prtdatep info,int *k);
void insertar(tpagina *raiz,prtdatep info);
void empujar(tpagina actual,prtdatep info,int *subearriba,plnodo *mediana,tpagina *nuevo);
void eliminar(tpagina *raiz,tipoclave d);
void eliminarregistro(tpagina actual,tipoclave cl,int *encontrado);
void dividirnodo(tpagina actual,plnodo cl,tpagina rd,int k,plnodo *mediana,tpagina *nuevo);
void meterhoja(tpagina actual,plnodo cl,tpagina rd,int k);
void quitar(tpagina actual,int k);
void sucesor(tpagina actual,int k);
void restablecer(tpagina actual,int k);
void moverderecha(tpagina actual,int k);
void moverizquierda(tpagina actual,int k);
void combina(tpagina actual,int k);
tpagina buscar(tpagina actual,tipoclave cl,int *indice);
main()
{
int op,salir=6,nm,cancelar,posicion;
int i;
system("color 1f");
tipoclave d;
prtdatep info,direcbus;
tpagina arbol;
tpagina bus;
system ("cls");
system("color 1f");
puts("\n\n\n\n") ;
puts("ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»");
puts("º º");
puts("º º");
puts("º BIENVENIDO AL PROGRAMA DE REGISTRO º");
puts("º º");
puts("º DE SUPERMERCADO º");
puts("º º");
puts("ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ");
printf("\n\nPresione enter para continuar...");
getch();
creararbolB(&arbol);
while(salir!=0)
{
system ("cls");
op=menu();
fflush(stdin);
switch(op)
{
case 1:
{
fflush(stdin);
info=getnode();
llenarrg(info);
insertar(&arbol,info);
}
break;
case 2:
{
fflush(stdin);
system ("cls");
puts("\n\n°°°°°°°°°° BUSQUEDA DE UN REGISTRO °°°°°°°°°°");
puts(" °°°°°°°°°° DE UN PRODUCTO °°°°°°°°°°");
printf("\n\n Digite el codigo del producto para mostrar toda su informacion:\n ");
scanf("%d",&d);
bus=buscar(arbol,d,&posicion);
if(bus==NULL)
{
puts("\n\nACTUALMENTE NO SE ENCUENTRA NINGUN REGISTRO");
getch();
}
else
{
for(i=0;i<=bus->cuenta;i++)
{
fflush(stdin);
if(bus->claves[i].tclave==d)
{
direcbus=bus->claves[i].direc;
system ("cls");
puts("\n\n°°°°°°°°°° RESULTADOS DE LA BUSQUEDA °°°°°°°°°°");
puts(" °°°°°°°°°° DEL PRODUCTO °°°°°°°°°°");
printf("\n\n\nNombre: %s\n\n",direcbus->nombre);
printf("\ncodigo: %d\n\n",d);
printf("\nDepartamento: %s\n\n",direcbus->departamento);
printf("\nfecha de vencimineto: %s\n\n",direcbus->codigo);
printf("\nNumero de Existencias: %s\n\n",direcbus->existen);
getch();
}
}
}
}
break;
case 3:
{
fflush(stdin);
system ("cls");
puts("\n\n°°°°°°°°°° ELIMINACION DE REGISTRO °°°°°°°°°°");
puts(" °°°°°°°°°° DEL PRODUCTO °°°°°°°°°°");
printf("\n\nUsted a elejido la opcion de eliminar un registro \n\n Digite el numero de codigo del producto :\n ");
scanf("%i", &d);
eliminar(&arbol,d);
}
break;
case 4:
{
fflush(stdin);
system ("cls");
puts("\n\n°°°°°°°°°° MODIFICACION DE UN REGISTRO °°°°°°°°°°");
puts(" °°°°°°°°°° DE UN PRODUCTO °°°°°°°°°°");
printf("\n\n Digite el codigo del producto para mostrar toda su informacion:\n ");
fflush(stdin);
scanf("%d",&d);
bus=buscar(arbol,d,&posicion);
if(bus==NULL)
{
puts("\n\nACTUALMENTE NO SE ENCUENTRA NINGUN REGISTRO");
getch();
}
else
{
for(i=0;i<=bus->cuenta;i++)
{
if(bus->claves[i].tclave==d)
{
direcbus=bus->claves[i].direc;
system ("cls");
puts("\n\n°°°°°°°°°° RESULTADOS DE LA BUSQUEDA PARA SU °°°°°°°°°°");
puts(" °°°°°°°°° MODIFICACION DEL PRODUCTO °°°°°°°°°°");
printf("\n\n\nNombre: %s\n\n",direcbus->nombre);
printf("\ncodigo: %d\n\n",d);
printf("\nDepartamento: %s\n\n",direcbus->departamento);
printf("\nfecha de vencimineto: %s\n\n",direcbus->codigo);
printf("\nNumero de Existencias: %s\n\n",direcbus->existen);
getch();
puts("\n\n¨ Realmente quiere modificarlo ?\n");
puts("Digite: 1 o 2\n1 -> Si, deseo modificarlo\n2 -> No, asi esta bien\n");
scanf("%d",&nm);
if(nm==1)
{
fflush(stdin);
llenarrg(direcbus);
bus->claves[i].tclave=direcbus->cod;
}
else
{
puts("\n Presione cualquier tecla para volver al menu principal");
getch();
}
}
}
}
}
break;
case 5:
{
fflush(stdin);
system ("cls");
printf("\nDesea realmente salir de la aplicacion: ");
printf("\n\nDIGITE>\n\n1-Aceptar\n\n2-Cancelar: ");
scanf("%d",&cancelar);
while(cancelar<1||cancelar>2)
{
system ("cls");
puts("\nERROR!!!... debe de digitar una operacion valida");
scanf("%d",&cancelar);
}
if(cancelar==1)
salir=0;
else
{
system ("cls");
puts("\nPresione enter para regresar al menu...");
getch();
}
}
break;
}
}
}
void creararbolB(tpagina *raiz)
{
*raiz=NULL;
}
prtdatep getnode(void)
{
prtdatep newnodo;
newnodo=(prtdatep)malloc(sizeof(date));
if(newnodo==NULL)
{
puts("\nError sin espacio en memoria...");
exit(1);
}
return newnodo;
}
void llenarrg(prtdatep registro)
{
char nom[20];
char cart[10];
tipoclave di;
char dept[40];
char exi[8];
system ("cls");
puts("\n\n°°°°°°°°°° INFORMACION DEL PRODUCTO °°°°°°°°°°");
puts("\n\nDigite la Informacion Solicitada Paran Dicho Producto");
printf("\n\n\nNombre del producto: ");
gets(nom);
strcpy(registro->nombre,nom);
printf("\nCodigo del Producto: ");
scanf("%d",&di);
registro->cod=di;
fflush(stdin);
printf("\nDepartamento: ");
gets(dept);
strcpy(registro->departamento,dept);
printf("\nfecha de vencimiento (intro duzcala sin guiones ni espacion): ");
gets(cart);
strcpy(registro->codigo,cart);
printf("\nexistencias del producto: ");
gets(exi);
strcpy(registro->existen,exi);
}
int menu(void)
{
int op;
system ("cls");
printf("\n\n°°°°°°°°°°°°°°°°°°°° MENU DEL SUPERMERCADO °°°°°°°°°°°°°°°°°°°°\n");
puts("\n1.- INSERTAR PRODUCTO EN EL SUPERMERCADO");
puts("\n2.- BUSCAR Y MOSTRAR EL PRODUCTO DEL SUPERMERCADO");
puts("\n3.- ELIMINAR PRODUCTO DEL SUPERMERCADO");
puts("\n4.- MODIFICAR PRODUCTO DEL SUPERMERCADO");
puts("\n5.- SALIR DEL PROGRAMA");
printf("\nDigite una opcion: ");
scanf("%d",&op);
while(op<1||op>5)
{
puts("\nErorr... Debe de elegir una operacion valida");
printf("\nDigite una opcion: ");
scanf("%d",&op);
}
return op;
}
int nodolleno(tpagina actual) //revisa si la pagina esta llena
{
return(actual->cuenta==m-1);
}
int nodosemivacio(tpagina actual) //revisa si la pagina esta semivacio
{
return(actual->cuenta<m/2);
}
int buscarnodoinsert(tpagina actual,prtdatep info,int *k)
{
int encontrado; //k indica la posicion dentro de las claves
if(info->cod<actual->claves[1].tclave) //la clave es menor que la clave de esta pagina
{
encontrado=0;
*k=0; //indica que debe seguir por el ptr a la pagina con las claves mas chicas
}
else //examinan las claves del nodo en orden descendete
{
*k=actual->cuenta;
while((info->cod<actual->claves[*k].tclave)&&(*k>1))
(*k)--;
encontrado=(info->cod==actual->claves[*k].tclave);
}
return encontrado;
}
void insertar(tpagina *raiz,prtdatep info)
{
int subearriba;
plnodo mediana;
tpagina p,nd;
empujar(*raiz,info,&subearriba,&mediana,&nd);
if(subearriba) //crece de nivel por la raiz, si la propagacion llega a la cima
{
p=(tpagina)malloc(sizeof(pagina));
p->cuenta=1;
p->claves[1].tclave=mediana->tclave;
p->claves[1].direc=mediana->direc;
p->ramas[0]=*raiz;
p->ramas[1]=nd;
*raiz=p;
}
}
void empujar(tpagina actual,prtdatep info,int *subearriba,plnodo *mediana,tpagina *nuevo)
{
int k; //posicion dentro del espacio de claves de pagina
int esta;
if(actual==NULL)
{
*subearriba=1;
(*mediana)->tclave=info->cod;
(*mediana)->direc=info;
*nuevo=NULL;
}
else
{
esta=buscarnodoinsert(actual,info,&k); //Baja hasta una rama vacia
if(esta)
{
puts("\nClave Duplicada");
getch();
*subearriba=0;
return;
}
empujar(actual->ramas[k],info,subearriba,mediana,nuevo);
//La recursion devuelve el contro; vuelve por el camino de busqueda
if(*subearriba) //sera 1 cuando su rama=null => inserta pues no podemos seguir bajando
{
if(nodolleno(actual))
dividirnodo(actual,*mediana,*nuevo,k,mediana,nuevo);
else
{
*subearriba=0;
meterhoja(actual,*mediana,*nuevo,k);
}
} //dejara de elevar medianas cuando pueda almenos una vez meterhoja
}
}
void meterhoja(tpagina actual,plnodo cl,tpagina rd,int k)
{
int i;
/*Desplaza a la derecha los elementos para hacer un hueco*/
for(i=actual->cuenta;i>=k+1;i--)
{
actual->claves[i+1].tclave=actual->claves[i].tclave;
actual->ramas[i+1]=actual->ramas[i];
}
actual->claves[k+1].tclave=cl->tclave;
actual->claves[k+1].direc=cl->direc;
actual->ramas[i+1]=rd;
actual->cuenta++;
}
void dividirnodo(tpagina actual,plnodo cl,tpagina rd,int k,plnodo *mediana,tpagina *nuevo)
{
int i,posmdna;
posmdna=(k<=m/2)? m/2: m/2+1; //posicion de clave mediana
(*nuevo)=(tpagina)malloc(sizeof(pagina)); //nuevo nodo
for(i=posmdna+1;i<m;i++)
{ //Es desplazada la mitad derecha al nuevo nodo la clave mediana se queda en el nodo origen
(*nuevo)->claves[i-posmdna].tclave=actual->claves[i].tclave;
(*nuevo)->ramas[i-posmdna]=actual->ramas[i];
}
(*nuevo)->cuenta=(m-1)-posmdna; //clave en el nuevo nodo
actual->cuenta=posmdna; //clave en el nodo hijo
//es insertada la clave y rama en el nodo que le corresponde
if(k>=m/2)
meterhoja(actual,cl,rd,k); //inserta el nodo origen
else
meterhoja(*nuevo,cl,rd,k-posmdna);
//se extrae la clave mediana del nodo origen
(*mediana)->tclave=actual->claves[actual->cuenta].tclave;
(*mediana)->direc=actual->claves[actual->cuenta].direc;
//rama del nuevo nodo es la rama de la mediana
(*nuevo)->ramas[0]=actual->ramas[actual->cuenta];
actual->cuenta--; //disminuye ya que se quita la mediana
}
void eliminar(tpagina *raiz,tipoclave d)
{
int encontrado;
eliminarregistro(*raiz,d,&encontrado);
if(encontrado)
{
printf("La eliminacion del registro se realizo existosamente");
getch();
if((*raiz)->cuenta==0)
{ /* La raiz esta vacia, libera el nodo y se establece la nueva raiz */
tpagina p = *raiz;
*raiz = (*raiz)->ramas[0];
free(p);
}
}
else
{
puts("El registro de ese producto no se encuentra\n");
getch();
}
}
void eliminarregistro(tpagina actual,tipoclave cl,int *encontrado)
{
int k;
if(actual!=NULL)
{
*encontrado = buscarnodo(actual,cl,&k); /* Busca la hoja con el cod */
if(*encontrado)
{
if(actual->ramas[k-1] == NULL)/* Pregunta si es actual un nodo hoja */
quitar(actual,k);/* Quita la clave de la hoja en nuestro caso el cod y todo el registro */
else
{
sucesor(actual,k);/* Encuentra la clave sucesora y hace el intercambio */
eliminarregistro(actual->ramas[k],actual->claves[k].tclave,encontrado); /* Como va con la pagina descendente, buscara hasta encontrar la pagina hoja con el que dato sucesor(que ya se cambio) y lo quitara */
}
}
else eliminarregistro(actual->ramas[k],cl,encontrado);
if(actual->ramas[k] != NULL)
if(actual->ramas[k]->cuenta < (m/2))
restablecer(actual,k);
}
else *encontrado = 0;
}
void quitar(tpagina actual,int k)
{
int j;
for(j=k+1;j<=actual->cuenta;j++)
{
actual->claves[j-1].tclave=actual->claves[j].tclave;
actual->claves[j-1].direc=actual->claves[j].direc;
actual->ramas[j-1]=actual->ramas[j];
}
actual->cuenta--;
}
void sucesor(tpagina actual,int k)
{
tpagina q;
q=actual->ramas[k];
while(q->ramas[0]!=NULL)
q=q->ramas[0]; //q referencia al nodo hoja
actual->claves[k].tclave=q->claves[1].tclave;
actual->claves[k].direc=q->claves[1].direc;
}
void restablecer(tpagina actual,int k)
{
//actual tiene la direccion del nodo antecedente de actual->ramas[k] que tiene menos claves que el minimo
if(k>0) //tiene hermano izquierdo
if(actual->ramas[k-1]->cuenta > m/2)
moverderecha(actual,k);
else
combina(actual,k);
else //solo tiene mano derecho
if(actual->ramas[1]->cuenta > m/2)
moverizquierda(actual,1);
else
combina(actual,1);
}
int buscarnodo(tpagina actual,tipoclave clbuscar,int *k)
{
int encontrado; //k indica la posicion dentro de las claves
if(clbuscar<actual->claves[1].tclave) //la clave es menor que la clave de esta pagina
{
encontrado=0;
*k=0; //indica que debe seguir por el ptr a la pagina con las claves mas chicas
}
else //examinan las claves del nodo en orden descendete
{
*k=actual->cuenta;
while((clbuscar<actual->claves[*k].tclave)&&(*k>1))
(*k)--;
encontrado=(clbuscar==actual->claves[*k].tclave);
}
return encontrado;
}
void moverderecha(tpagina actual,int k)
{
int j;
tpagina nodoproblema=actual->ramas[k];
tpagina nodoizqdo=actual->ramas[k-1];
for(j=nodoproblema->cuenta;j>=1;j--)
{
nodoproblema->claves[j+1].tclave=nodoproblema->claves[j].tclave;
nodoproblema->claves[j+1].direc=nodoproblema->claves[j].direc;
nodoproblema->ramas[j+1]=nodoproblema->ramas[j];
}
nodoproblema->cuenta++;
nodoproblema->ramas[1]=nodoproblema->ramas[0];
//baja la clave del nodo padre
nodoproblema->claves[1].tclave=actual->claves[k].tclave;
nodoproblema->claves[1].direc=actual->claves[k].direc;
//sube la clave del hermano izquierdo al nodo clave para reemplazar la que antes bajo
actual->claves[k].tclave=nodoizqdo->claves[nodoizqdo->cuenta].tclave;
actual->claves[k].direc=nodoizqdo->claves[nodoizqdo->cuenta].direc;
nodoproblema->ramas[0]=nodoizqdo->ramas[nodoizqdo->cuenta];
nodoizqdo->cuenta--;
}
void moverizquierda(tpagina actual,int k)
{
int j;
tpagina nodoproblema=actual->ramas[k-1];
tpagina nododrcho=actual->ramas[k];
nodoproblema->cuenta++;
nodoproblema->claves[nodoproblema->cuenta].tclave=actual->claves[k].tclave;
nodoproblema->claves[nodoproblema->cuenta].direc=actual->claves[k].direc;
nodoproblema->ramas[nodoproblema->cuenta]=nododrcho->ramas[0];
actual->claves[k].tclave=nododrcho->claves[1].tclave;
actual->claves[k].direc=nododrcho->claves[1].direc;
nododrcho->ramas[1]=nododrcho->ramas[0];
nododrcho->cuenta--;
for(j=1;j<=nododrcho->cuenta;j++)
{
nododrcho->claves[j].tclave=nododrcho->claves[j+1].tclave;
nododrcho->claves[j].direc=nododrcho->claves[j+1].direc;
nododrcho->ramas[j]=nododrcho->ramas[j+1];
}
}
void combina(tpagina actual,int k)
{
int j;
tpagina nodoizqdo, q;
q=actual->ramas[k];
nodoizqdo=actual->ramas[k-1];
//"baja" clave mediana desde el nodo padre
nodoizqdo->cuenta++;
nodoizqdo->claves[nodoizqdo->cuenta].tclave=actual->claves[k].tclave;
nodoizqdo->claves[nodoizqdo->cuenta].direc=actual->claves[k].direc;
nodoizqdo->ramas[nodoizqdo->cuenta]=q->ramas[0];
//"mueve" claves del nodo derecho
for(j=1;j<=q->cuenta;j++)
{
actual->claves[j].tclave=actual->claves[j+1].tclave;
actual->claves[j].direc=actual->claves[j+1].direc;
actual->ramas[j]=actual->ramas[j+1];
}
actual->cuenta--;
free(q);
}
tpagina buscar(tpagina actual,tipoclave cl,int *indice)
{
if(actual==NULL)
{
return NULL;
}
else
{
int esta;
esta=buscarnodo(actual,cl,indice);
if(esta)
return actual;
else
return buscar(actual->ramas[*indice],cl,indice);
}
}