프로그래밍[Univ]/데이터구조

[리스트]연결리스트(링크드리스트) 각 단계별 해설 有 구현 5/24

Cloud Travel 2011. 5. 24. 11:23

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

typedef struct nodetype{  // 연결리스트 node를 만듭니다
 int data;
 struct nodetype *next_ptr;
 // node(노드)는 자료 + 연결 이라고했죠?
 // data라는 자료와 다음 노드를 연결하는 포인터 next_ptr로 구성했습니다
}node;

typedef struct listtype{  // 리스트의 형태를 구성합니다.
 int count;
 node headnode;        // 해더 노드를 사용했습니다.
}list;

list *makelist(){ // 리스트를 생성하는 함수입니다.
 list *returnlist; 
 returnlist = (list *)malloc(sizeof(list));
 if ( returnlist != NULL ){  // 생성 후 반환할 리스트를 만들어 동적할당후 검사 단계
  memset(returnlist,0,sizeof(list)); // 동적할당이 잘됬다면 list의 변수를 0으로 초기화!!
 }else{
  printf("Error\n");
  return 0;
 }
 return returnlist;  // 생성된 리스트를 반환합니다.
}

void Add(list *Plist,int p,node d){  // 리스트에 자료를 추가하는 함수입니다.
 if ( p < 0 || p > Plist -> count ){  // 위치의 타당성을 검사합니다.
  printf("Error!! value of position\n");
 }else{
  int i;
  node *temp = &Plist -> headnode;
  // temp라는 임시저장소를 만듭니다. 앞으로 temp는 자주 나올텐데...
  // 리스트 형태에서 자료사이를 이동하는 역할을 해준다고 생각하면 됩니다.
  node *newnode = (node *)malloc(sizeof(node));  // 받은 data노드를 저장하여 연결시키는 node입니다.
  if ( newnode != NULL ){  // 동적할당이 잘되었는지 검사 후~
   *newnode = d;
   for( i = 0 ; i < p ; i++ ){
    temp = temp -> next_ptr;  // temp를 이용하여 원하는 위치로 이동 후~
   }
   newnode -> next_ptr = temp -> next_ptr;  // 자료 값을 넣어 줍니다.
   temp -> next_ptr = newnode;              // 전에 리스트에서 설명한 순서에 의거합니다~!!
   Plist -> count++;    // 저장된 자료의 개수를 한단계 올립니다.
   return ;
  }else{
   printf("Error!!\n");
   return ;
  }
 }
}

void Del(list *Plist,int p){  // 리스트에서 자료를 제거하는 함수입니다
 int i;
 node *temp = &Plist -> headnode;  // 역시나 temp를 생성했습니다.
 node *free_node;  // free_node는 나중에 삭제된 자료가 메모리상에서 남아있지 않게 하기 위해서 필요합니다.
 if ( p < 0 || p >= Plist -> count ){  // 위치의 타당성을 점검한 후~
  printf("Error!! value of positon\n");
  return;
 }else{
  for ( i = 0 ; i < p ; i++ ){
   temp = temp -> next_ptr;  // 원하는 위치로 이동한 후~
  }
  free_node = temp -> next_ptr;  // 삭제될 위치의 노드를 free_node에 저장합니다.
  temp -> next_ptr = temp -> next_ptr -> next_ptr;  // 후에 과감히 삭제되는 노드의 연결을 끈고,
  Plist -> count--;  // 저장된 자료의 개수를 한단계 내립니다.
  if ( free_node != NULL ){  // free_node에 값이 잘들어있는지를 본후에
   free(free_node);  // 메모리상에서 삭제 시켜줍니다~
  }
  return;
 }
}

void Seek(list *Plist, int p){  // 원하는 위치의 데이터를 찾는 함수입니다.
 // 배열에서 구현한것과 비교해보면 줄수도 길어지고 복잡해보이죠?
 int i;
 node *temp = &Plist -> headnode;  // 역시나 temp의 등장!!
 if ( p < 0 || p >= Plist -> count ){  // 위치의 타당성을 점검한후~
  printf("Error!! value of positon\n");
  return;
 }else{
  for ( i = 0 ; i <= p ; i++ ){
   temp = temp -> next_ptr;  // 원하는 위치로 이동 후~
  }
  printf("%d번의 자료 : %d\n",p,temp -> data);  // 출력해줍니다~
  return ;
 }
}
// 개인의 편의에 따라 return 타입을 정해줘 return해도 됩니다~

void Display(list *Plist){  // 모든 자료를 보는 함수입니다.
 node *temp = NULL;  // temp가 있죠?
 int i = 0;
 temp = &Plist -> headnode;
 for ( i = 0 ; i < Plist -> count ; i++ ){
  temp = temp -> next_ptr;  // 모든 데이터를 훑으면서 자료를 출력합니다.
  printf("%d번째 자료 : %d\n",i,temp -> data);
 }
}

//main은 언제나 그랬듯이.. 자신의 편이를 생각해서...
  
int main(){
 list *LL;
 LL = makelist();
 
 while(1){
  int select;
  int position;
  node datanode;
  printf("\n\n\n현재 %d개의 자료 저장중\n",LL -> count);
  printf("기능을 선택해주십시요.\n");
  printf("1.자료저장\t2.자료삭제\t3.자료검색\t4.전체자료보기\t5.종류\n");
  scanf("%d",&select);
  switch(select){
   case 1:
    printf("저장 위치 : ");
    scanf("%d",&position);
    printf("저장 자료 : ");
    scanf("%d",&datanode.data);
    Add(LL,position,datanode);
    break;
   case 2:
    printf("삭제할 자료 위치 : ");
    scanf("%d",&position);
    Del(LL,position);
    break;
   case 3:
    printf("찾을 자료 위치 : ");
    scanf("%d",&position);
    Seek(LL,position);
    break;
   case 4:
    Display(LL);
    break;
   case 5: 
    if( LL != NULL ){
     free(LL);  // 마지막 종류시에는 자료를 메모리에서도 지워줍니다.
    }
    return ;
   default:
    printf("You don't press colect number");
  }
 }
}

--------------------------------------------------------------------------------------------------

위에서 구현한 것을 그림으로 보면


배열과 비교했을 때... 일단 자료 형식이 node라는 특수한 형식으로 이뤄져 있다는 것..

그리고 해당 Index를 찾기 위해서는 처음부터 해당 위치까지 이동해야 된다는 점...(단점)

저장할수 있는 max를 정해주지 않아도 된다는 것...(장점) 메모리의 여유가 된다면 얼마든지 연결이 가능하다.

다음에는 원형 연결리스트, 이중 연결리스트를 알아보고, 응용분야를 알아보도록하자~!!