IT&컴퓨터공학/자료구조&알고리즘
[05]C언어 연결리스트 :: 단일연결리스트 데이터 탐색/삭제/출력
yan_z
2019. 2. 12. 16:42
- 데이터 탐색
이러한 단일연결리스트가 있을때 데이터 탐색을 해볼까요 ?
탐색은 아주 쉬워요 !
데이터 탐색의 과정은 위 그림처럼
Cur 이라는 노드 포인터로 Head 다음부터 마지막 NULL 까지 차례대로 넘어가면서 찾는 데이터가 있으면 출력하고,
없으면 원하는 데이터가 없다고 출력합니다.
이 과정을 코드로 나타내보면
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | void Search(List *L, int number) { Node *cur = L->head; // cur 이 리스트의 head를 가르킨다. if (L->head->next == NULL) { printf("저장된 데이터가 없습니다 !\n"); } else // 그 외에 ( head 와 NULL 사이에 하나라도 데이터가 있다면 ) { while (cur!=NULL) //cur 이 NULL 을 만나면 while문을 나간다. { if (cur->data == number) //cur 이 가르키는 데이터가 찾는 데이터이면 { printf("%d\n", number); //출력하고 return; // 종료한다 } cur = cur->next; // 아니면 다음데이터로 } if (cur == NULL) printf("찾는 데이터가 없습니다!\n"); // NULL 까지 } } | cs |
이렇게 나타낼 수 있겠네요 !
- 데이터 삭제
위의 사진에서 20이라는 노드를 삭제하는 과정은,
① 20이라는 노드를 찾는다. ( 위의 데이터 탐색을 사용해서 )
② 20이라는 노드의 뒤에 노드와 앞의 노드를 연결시켜주고
③ 20이라는 노드는 free를 해준다.
이렇게 되겠네요 !
그럼 한 번 그림으로 볼까요 ?
이렇게 cur이라는 포인터가 20을 찾았을 때,
앞의 노드와 뒤의 노드 ( 30 과 10 ) 을 어떻게 연결해 줄 수 있을까요 ?
10은 cur->next 로하면 될거같은데 , 30은 ?
위의 방법처럼 하면 30을 나타낼 수 있는 방법이 없어요 !
그래서
이렇게 cur->next 가 우리가 찾는 20이어야 합니다.
cur은 우리가 찾는 노드의 바로 전 노드로 하면 되겠죠 ?
이 과정을 코드로 나타내보면,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | void Remove(List *L, int number) { Node *cur = L->head; Node *rpos; // free 될 노드를 가르킬 노드 if (L->head->next == NULL) // 데이터가 하나도없으면 { printf("저장된 데이터가 없습니다 !\n"); } else // 데이터가 하나라도 있다면 { while (cur->next != NULL) //cur의 next가 null이 아니면 계속 돈다 { if (cur->next->data == number) { rpos = cur->next; // cur->next를 free 시켜야 하므로 cur->next = cur->next->next; // 앞의 노드가 가르키는게(cur->next) 뒤(cur->next->next)의 노드이다. free(rpos); // free return; } cur = cur->next; } if (cur->next == NULL) printf("찾는 데이터가 없습니다!\n"); } } | cs |
이렇게 되겠네요 ! 위에서 본 탐색과 비슷하죠?
- 데이터 출력
데이터 출력은 정말 쉬운데요 !
이건 따로 설명없이 코드만 보셔도 충분히 이해하실 수 있을것 같습니다 !
코드를 써보자면,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | void Print(List *L) { Node *cur; if (L->head->next == NULL) printf(" 저장된 데이터가 없습니다 !\n"); else { cur = L->head->next; while (cur != NULL) { printf(" %d", cur->data); cur = cur->next; } } } | cs |
이렇게 나타낼 수 있겠네요 .
앞에서 봤던 단일연결리스트의 초기화/삽입/탐색/삭제/출력의 모든 코드를 합쳐보면
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #include <stdio.h> #include <stdlib.h> typedef struct _Node { int data; // int 형 데이터를 담는공간 struct _Node *next; // 연결의 도구 ! ( 화살표 ) }Node; typedef struct _List{ Node *head; int numofData; }List; Node* getNode() { Node *new = (Node*)malloc(sizeof(Node)); new->next = NULL; return new; } List* initList() { List *L = (List*)malloc(sizeof(List)); L->head = getNode(); L->numofData = 0; return L; } void Insert(List *L, int number) { Node *newNode = getNode(); newNode->data = number; if (L->head->next == NULL) // head 의 next가 가르키는것이 NULL 이면 { newNode->next = NULL; L->head->next = newNode; } else // 그 외에 ( head 와 NULL 사이에 하나라도 데이터가 있다면 ) { newNode->next = L->head->next; L->head->next = newNode; } } void Search(List *L, int number) { Node *cur = L->head; // cur 이 리스트의 head를 가르킨다. if (L->head->next == NULL) { printf("저장된 데이터가 없습니다 !\n"); } else // 그 외에 ( head 와 NULL 사이에 하나라도 데이터가 있다면 ) { while (cur!=NULL) { if (cur->data == number) { printf("%d\n", number); return; } cur = cur->next; } if (cur == NULL) printf("찾는 데이터가 없습니다!\n"); } } void Remove(List *L, int number) { Node *cur = L->head; Node *rpos; // free 될 노드를 가르킬 노드 if (L->head->next == NULL) // 데이터가 하나도없으면 { printf("저장된 데이터가 없습니다 !\n"); } else // 데이터가 하나라도 있다면 { while (cur->next != NULL) //cur의 next가 null이 아니면 계속 돈다 { if (cur->next->data == number) { rpos = cur->next; // cur->next를 free 시켜야 하므로 cur->next = cur->next->next; // 앞의 노드가 가르키는게(cur->next) 뒤(cur->next->next)의 노드이다. free(rpos); // free return; } cur = cur->next; } if (cur->next == NULL) printf("찾는 데이터가 없습니다!\n"); } } void Print(List *L) { Node *cur; if (L->head->next == NULL) printf(" 저장된 데이터가 없습니다 !\n"); else { cur = L->head->next; while (cur != NULL) { printf(" %d", cur->data); cur = cur->next; } } } | cs |
이렇게 되겠네요 !