C++프로그래밍

2013.04.24~25_연결리스트_함수활용

성엽이 2013. 4. 24. 17:53

▶ 연결리스트 함수의 활용_

 

#include < stdio.h >
#include < process.h >
#include < stdlib.h >

typedef struct node 
{
  char data;
  struct node *next;
}NODE;

void print_list(NODE *);
int count(NODE *);
void loop_free(NODE *);
void free_list(NODE *);
void concatenate(NODE *, NODE *);
NODE *search( NODE *, char );
NODE *append( NODE *, NODE * );
  
int main()
{
  FILE *fp;  
  NODE *temp = NULL;
  NODE *list = NULL;
  NODE *list2 = NULL;

  char ch;
  
  if((fp = fopen("10-5.txt","r")) == NULL )
  {
    printf("file open error!");
    exit(-1);
  }

  fscanf(fp,"%c"&ch);

  while0 == feof(fp) )
  {
    temp = (NODE *)malloc(sizeof(NODE));
    temp->data = ch;
    temp->next = NULL;
    list = append(list, temp);
    fscanf(fp, "%c"&ch);
  }

  fclose(fp);

  if((fp = fopen("10-5.txt","r")) == NULL )
  {
    printf("file open error!");
    exit(-1);
  }

  fscanf(fp,"%c"&ch);

  while0 == feof(fp) )
  {
    temp = (NODE *)malloc(sizeof(NODE));
    temp->data = ch;
    temp->next = NULL;
    list2 = append(list2, temp);
    fscanf(fp, "%c"&ch);
  }

  fclose(fp);  

  print_list(list);
  print_list(list2);
  
  concatenate(list, list2);

  print_list(list);

  temp = search( list, 'l');
  print_list(temp);  
  
  printf("number of list : %d\n", count(list));
  
  loop_free(list);

  //free_list(list2);  

  return 0;
}

void print_list(NODE *head)  // 연결리스트를 인수로 넘겨받아 내용을 출력하는 함수.
{
  if( head == NULL )         // 연결리스트의 주소가 들어가는 next 부분이 NULL 이면 
  {                          // NULL\n 을 출력한다.(마지막부분에 나올 것이다.)
    printf("NULL\n");
  }
  else
  {
    printf("%c ==> ", head->data);    // NULL 을 만나기 전까지 data를 하나씩 불러와서 출력하고
    print_list( head->next );         // 다음 주소부분(next) print_list 함수로 불러온다.
  }
}

int count(NODE *head)  // 연결리스트의 노드의 개수를 헤아리는 함수
{
  if( head == NULL )    // list 에서 NULL 을 만나기 전까지 else 문이 실행됨.
  {
    return 0;
  }
  else
  {
    return(1 + count( head->next ));   // 1 + 1 + 1 + ..count( head->next ) 반복해서 불러줌.
  }                                     // NULL 값을 만나면 위에 if 문을 만나서 노드의 갯수만큼 돌려줌.
}

void loop_free(NODE *head)  // 연결리스트의 메모리를 해제하는 함수
{
  NODE *temp;
  NODE *current;
    
  for( temp = head; temp != NULL ; temp = current)
  {
    current = temp->next;      // temp = head: list 에 있는 현재주소를 받고, temp->next: 다음 연결리스트를   
    free(temp);                // current 에다가 대입한다. 그리고 현재의 주소가 들어가있는 temp 의 메모리를 해제한다.
  }                            // 반복.
}

void free_list(NODE *head)  // 재귀함수를 이용하여 연결리스트의 메모리를 해제하는 함수
{
  if( head != NULL )        
  { 
    free_list(head->next);   // free_list 함수로 NULL 을 만날때까지 if 문이 안에서 반복

    free(head); // NULL 을 만나면 실행하지 않고 하나씩 전에 실행했던 if 문을 해제함.
  }

}

void concatenate(NODE *first, NODE *second)  // 두 리스트를 연결하는 함수
{
  if(first->next == NULL)    // 마지막부분인 NULL 을 만나면 
  {                          
    first->next = second;    // 그부분에 새로 만든 리스트를 연결해줌.
  }
  else
  {
    concatenate( first->next, second);   // NULL 을 만날때까지 next 시켜줌.
  }
}

NODE *search( NODE *head, char ch )  // 리스트내의 특정 데이터를 가진 노드를 찾는 함수
{
  NODE *walker = head;
  
  while((walker != NULL) && ((walker->data) != ch)) // 끝까지 가서 (NULL) 비교해서 찾는다 ( (walker->data) != ch )
  {
    walker = walker->next;  // 다음 노드로 이동
  }                         // 입력한 ch 에 넣어준 값과 NULL 이 같지않으면 다음 리스트로 이동
  if( walker == NULL )      // 만약 NULL 을 만나서 끝부분이면 반환값으로 NULL 을 반환
  {
    return(NULL);    
  }
  else
  {
    return walker;       // NULL 이 아닌 입력해준 값이 맞으면 그 반환값이 있는 위치를 반환
  }
}  

NODE *append( NODE *list, NODE *temp )  // 새로운 노드를 연결리스트의 뒷부분으로 추가하는 함수
{
  NODE *current = list;     // list 구조체의 주소를 current 구조체로 넣어서 옮겨줄것임.
  
  if(list == NULL)
  {
    list = temp;       // 만약 list 구조체가 끝이면 바로 뒤에다가 가져다 붙임.
  }
  else
  {
    while( current->next != NULL )
    {
      current = current->next;    // current 구조체가 끝까지(NULL) 갈때까지 반복문을 돌림.
    }
    current->next = temp;   // NULL을 만나 끝부분에 가면 거기다 새로 연결할 부분(temp) 를 넣어줌.
  }
  return(list);
}