Data structures - 1. tree :: namecart program(자료구조 - 트리 명함 프로그램)




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <conio.h>

typedef struct namecard{
 struct namecard *left;
 char company[30];
 char position[20];
 char name[20];
 char tel[20];
 struct namecard *right;
}NC;

int Input(NC *root, NC input_tree);
void Output(NC *tree);
NC *Search(NC *tree, char *key);
void Update(NC **tree, char *key, int data_num);
void Delete(NC **tree, char *key);
int Loaddata(NC **tree, char *loadfile);
void Savedata(NC *tree, int data_num, char *loadfile);

char list[4][9]={"Company","Position","Name","Tel"};

#include <ham.h>

main()
{
 NC *tree=NULL, *ptr;
 NC input_tree; // 입력받을거

 int data_num=0;
 int i=0,j;
 char ch;
 char name_key[20];  // 검색 이름
 char loadfile[50];

 printf("로드할 데이터의 위치를 입력하세요\n::");
 scanf(" %s",loadfile);
 system("cls");

 data_num=Loaddata(&tree, loadfile);
 

 while(1)
 {

  printf("Namecard Management Program\n");
  printf("===========================\n");
  printf("*DATA INPUT(I)\n");
  printf("*DATA OUTPUT(O)\n");
  printf("*DATA SEARCH(S)\n");
  printf("*DATA UPDATE(U)\n");
  printf("*DATA DELETE(D)\n");
  printf("*****EXIT(E)*****\n");
  printf("Select the work to do : ");
  scanf(" %c", &ch);
 
  if(ch >= 'A' && ch <= 'Z')
  {
   ch += 'a'-'A';
  }

  switch(ch){
  case 'i':
  
   printf("Namecard data Input\n입력을 마치려면 (x x x x) 입력\n");
   printf("Company    Positon    Name    Tel\n");
   printf("========================================\n");
 
   while(1)
   {
    scanf(" %s %s %s %s", input_tree.company, input_tree.position, input_tree.name, input_tree.tel);
    if(strcmp(input_tree.company,"x")==0) break;
    if(!tree){
    tree=(NC*)malloc(sizeof(NC));
    strcpy(tree->company,input_tree.company);
    strcpy(tree->position,input_tree.position);
    strcpy(tree->name,input_tree.name);
    strcpy(tree->tel,input_tree.tel);
    tree->left=tree->right=NULL;
    data_num++;
    }
    else{
     Input(tree,input_tree);
     data_num++;
    }
   }
   printf("Enter...");
   getch();

   break;
  

  case 'o':

   printf("%15s\t%10s\t%10s\t%10s\n",list[0],list[1],list[2],list[3]);
   printf("==============================================================\n");
   Output(tree);
   printf("Enter...");
   getch();

   break;

  case 's':

   printf("검색할이름 입력: ");
   scanf("%s", name_key);
   ptr=Search(tree, name_key);
   if(ptr){
    printf("%15s\t%10s\t%10s\t%10s\n",list[0],list[1],list[2],list[3]);
   printf("==============================================================\n");
    printf("%15s\t%10s\t%10s\t%10s\n", ptr->company, ptr->position, ptr->name, ptr->tel);
   }
   else
    printf("없는 명함입니다.\n");
   printf("Enter...");
   getch();

   break;

  case 'u':

   printf("수정할 이름 입력: ");
   scanf(" %s", name_key);
   ptr=Search(tree, name_key);
   if(ptr){
    Update(&tree, name_key, data_num);
   }
   else
    printf("없는 명함입니다.\n");
   printf("Enter...");
   getch();   

   break;

  case 'd':

   printf("삭제할 이름 입력: ");
   scanf(" %s", name_key);
   ptr=Search(tree, name_key);
   if(ptr){
    printf("삭제하였습니다.\n");
    Delete(&tree,name_key);
   }
   else
    printf("없는 명함입니다.\n");
   
   printf("Enter...");
   getch();

   break;

  default:
   break;
  }

  if(ch == 'e'){
   FILE *f;

   f=fopen(loadfile, "wt");
   fclose(f);

   Savedata(tree,data_num,loadfile);
   break;
  }

  system("cls");
  }
}

int Input(NC *root, NC input_tree)
{
 NC *tptr = root, *before;
 int cmp;

 while (tptr)
 {
  cmp = strcmp(input_tree.name, tptr->name);
  if(cmp < 0)
  {
   before = tptr;
            tptr = tptr -> left;
  }
  else if(cmp > 0)
  {
   before = tptr;
            tptr = tptr -> right;
  }
  else{
   before = tptr;
   tptr = tptr -> right;
  }
   //return 0;  
 }
 tptr = (NC *)malloc(sizeof(NC));
 strcpy(tptr->company,input_tree.company);
 strcpy(tptr->position,input_tree.position);
 strcpy(tptr->name,input_tree.name);
 strcpy(tptr->tel,input_tree.tel);
 tptr->left = tptr->right = NULL;
 if(cmp < 0) before -> left = tptr;
 else before -> right = tptr;
    return 1;
}

NC *Search(NC *tree, char *key)
{
 NC *tptr=tree;
 int cmp;
  
 while(tptr)
 {
  cmp = strcmp(key, tptr->name);
  if(cmp < 0)
   tptr=tptr->left;
  else if(cmp > 0)
   tptr=tptr->right;
  else       // FOUND !!
   return tptr;
 }

 return NULL;      // NOT FOUND
}

void Delete(NC **tree, char *key)
{
 NC * previous, * parent, * del, * move = NULL;
 
    previous = del = * tree;
 
    while(del){
        if(strcmp(del->name, key) == 1){
            del = (previous = del)->left;
        }else if(strcmp(del->name, key) == -1){
            del = (previous = del)->right;
        }else{
            break;
        }
    }
   
    if(del == NULL){ return; }

    if(del->left){
        move = (parent = del)->left;
        while(move->right){
            move = (parent = move)->right;
        }   
        move->right = del->right;
        if(parent != del){
            parent->right = move->left;
            move->left = del->left;
        }
    }else if(del->right){
        move = (parent = del)->right;
        while(move->left){
            move = (parent = move)->left;
        }    
        move->left = del->left;
        if(parent != del){
            parent->left = move->right;
            move->right = del->right;
        }
    }else{
        (strcmp(previous->name, key) == 1) ? previous->left = NULL : previous->right == NULL;
    }
 
    if(del == previous){
        * tree = move;
    }else if(move != NULL){
        if(strcmp(previous->name, key) == 1){
            previous->left = move;
        }else{
            previous->right = move;
        }
    }
    free(del);
}

void Output(NC *tree)
{
 NC *tptr=tree;

 if(tptr == NULL)
  return;
 Output(tptr->left);
 printf("%15s\t%10s\t%10s\t%10s\n", tptr->company, tptr->position, tptr->name, tptr->tel);
 Output(tptr->right);
}

void Update(NC **tree, char * key, int data_num)
{
 NC tmp;
 printf("새 데이터 입력입력\n");
 printf("Company    Positon    Name    Tel\n");
 printf("========================================\n");
 scanf("%s %s %s %s", tmp.company, tmp.position, tmp.name, tmp.tel);
 printf("%15s\t%10s\t%10s\t%10s\n",list[0],list[1],list[2],list[3]);
 printf("==============================================================\n");
 tmp.left=tmp.right=NULL;
 if(data_num==1){
  **tree=tmp;
  Delete(tree,key);
  printf("%15s\t%10s\t%10s\t%10s\n", tmp.company, tmp.position, tmp.name, tmp.tel);
  return;
 }
 Input(*tree,tmp);
 Delete(tree,key);
 printf("%15s\t%10s\t%10s\t%10s\n",tmp.company, tmp.position, tmp.name, tmp.tel);
}

int Loaddata(NC **tree, char *loadfile)
{
 NC *ptr;
 NC tmp;
 int data_num,i;
 
 FILE *f;


 if(!(f=fopen(loadfile, "rb"))){
  return 0;
 }
 
 fseek(f,0,SEEK_END);
 if(ftell(f)==0){
  fclose(f);
  return 0;
 }

 fseek(f,0,SEEK_SET);

 ptr=(NC*)malloc(sizeof(NC));

 fscanf(f,"%d",&data_num);
 fread(ptr,sizeof(NC),1,f);
 ptr->left=ptr->right=NULL;
 *tree = ptr;

 if(data_num==1){
  fclose(f);
  return 0;
 }

 for(i=1;i<data_num;i++){
  fscanf(f,"%d",&data_num);
  fread(&tmp,sizeof(NC),1,f);
  Input(*tree,tmp);
 }
 fclose(f);
 return data_num;
}

void Savedata(NC *tree, int data_num, char *loadfile)
{
 FILE *f;

 if(!(f=fopen(loadfile, "ab"))){
  printf("error");
 }
 
 if(tree == NULL){
  fclose(f);
  return;
 }

 Savedata(tree->left, data_num, loadfile);
 fprintf(f,"%d",data_num);
 fwrite(tree,sizeof(NC),1,f);
 Savedata(tree->right, data_num, loadfile);
}