[자료구조 - C언어] 자료구조 제13강: 이중 연결 리스트
2022. 10. 26. 00:32ㆍCS/자료구조
728x90
//공부 기록용 포스팅입니다. 틀린 부분이 있을 경우 댓글로 알려주시면 감사합니다! 😎
1. 단방향 연결 리스트와 이중 연결 리스트
- 단방향 연결 리스트(single linked list)
- 어떤 노드의 앞에 새로운 노드를 삽입하기 어려움
- 삭제할 노드의 앞 노드가 필요함
- 단방향 순회만 가능
- 양방향 연결 리스트(double linked list) = 이중 연결 리스트
- 양방향 순회가 가능
- 각각의 노드가 다음(next) 노드와 이전(previous) 노드의 주소를 가지는 연결 리스트
2. 양방향 연결 리스트의 Node
struct node{
char *data;
struct node *next;
struct node *prev;
};
typedef struct node Node;
Node *head; //연결리스트의 첫 번째 노드 주소 저장
Node *tail; //연결리스트의 마지막 노드 주소 저장
int size=0; //현재 노드 개수
3. 어떤 노드 앞에 노드 삽입
- 단방향 연결 리스트에서는 노드를 중간에 삽입하려면
- 앞 노드의 주소를 통해 → 그 노드의 바로 뒤에 삽입할 수 있었다.
- 양방향 연결 리스트에서는 prev와 next를 통해 어떤 노드의 앞에 노드를 삽입할 수 있다.
//어떤 노드 앞에 노드 삽입
//1. 새로운 노드 생성
Node *new_node = (Node *)malloc(sizeof(Node));
new_node->data = "by";
//2. 새로운 노드의 링크를 먼저 연결
new_node->next = p;
new_node->prev = p->prev;
//3. 노드의 앞 뒤 노드 링크 정리
p->prev->next = new_node;
p->prev = new_node;
3-1. add_after(Node *pre, char *item)
- case
- empty 리스트
- 제일 앞/뒤
- 중간
void add_after(Node *pre, char *item){
//새 노드 생성
Node *new_node = (Node*)malloc(sizeof(Node));
new_node->data = item;
new_node->prev = NULL;
new_node->next = NULL;
//연결리스트에 노드가 하나도 없는 empty list인 경우
//head==NULL이면 empty list
//empty list 이기 때문에 pre도 NULL
if(pre==NULL && head==NULL){
//삽입하는 새 노드가 유일한 노드
//첫 번째이자 마지막 노드
head=new_node;
tail=new_node;
}
//맨 앞에 삽입하는 경우
//head!=NULL일 때 pre==NULL이면 제일 앞에 삽입
else if(pre==NULL){
//새로운 노드의 다음 노드는 지금 head가 가리키는 노드
new_node->next=head;
//현재 head가 가리키는 노드의 앞 노드는 새로운 노드
head->prev = new_node;
//head가 새로운 노드를 가리키게 함
head=new_node;
}
//맨 마지막에 삽입하는 경우
else if(pre==tail){
//새로운 노드의 앞 노드는 맨 마지막 노드
new_node->prev = tail;
//원래 맨 마지막이었던 노드의 뒤에 새로운 노드 연결
tail->next = new_node;
//tail이 새로운 노드를 가리키게 함
tail = new_node;
}
//중간 삽입
else{
new_node->prev=pre;
new_node->next=pre->next;
pre->next->prev=new_node;
pre->next=new_node;
}
size++;
}
4. 노드 삭제
- 단방향 연결 리스트에서 노드를 삭제하기 위해서는 앞 노드의 주소가 필요하지만
- 양방향 연결 리스트에서는 삭제하고자 하는 노드만 필요로 한다.
//노드 삭제
p->prev->next = p->next;
p->next->prev = p->prev;
4-1. remove(Node *p)
- p가 유일한 노드
- head=NULL, tail=NULL
- p가 head
- head만 수정
- p가 tail
- tail만 수정
- 중간 삽입 ~ head와 tail은 변경 X
void remove(Node *p){
//p가 유일한 노드인 경우
if(head==p && tail==p){
head=NULL;
tail=NULL;
free(p);
}
//p가 head인 경우
else if(head==p){
p->next->prev=NULL;
head=p->next;
free(p);
}
//p가 tail인 경우
else if(tail==p){
p->prev->next=NULL;
tail=p->prev;
free(p);
}
//중간 삭제
else{
p->prev->next=p->next;
p->next->prev=p->prev;
free(p);
}
}
5. add_ordered_list(char *item)
- add_after을 사용해서 정렬된 위치에 노드를 삽입하는 함수
- 역방향으로 순회를 해서 처음으로 ‘보다 작은’ 노드를 찾고, 그 뒤에 삽입(add_after)
//add_after을 사용해서
//정렬된 위치에 노드를 삽입하는 함수
//역방향 순회 ~ 처음으로 '보다 작은'노드를 찾고 그 뒤에 삽입
void add_ordered_list(char *item){
Node *p = tail;
//item보다 p->data가 클 동안
while(p!=NULL && strcmp(p->data, item)<0)
//앞으로 이동
p=p->prev;
add_after(p, item);
}
- empty list
- p도 NULL, head도 NULL ~ add_after의 첫 번째 조건에 해당
- 가장 큰 입력값(= 마지막에 삽입)
- p는 tail, head는 NULL 아님 ~ add_after의 세 번째 조건에 해당
- 가장 작은 입력값(= 처음에 삽입)
- p는 NULL ~ add_after의 두 번째 조건에 해당
6. 원형(circular) 리스트
- 원형 연결 리스트
- 마지막 노드의 다음 노드가 첫 번째 노드가 되는 단순 연결 리스트
- 원형 이중 연결 리스트
- 마지막 노드의 다음 노드가 첫 번째 노드가 되고
- 첫 노드의 이전 노드가 마지막 노드가 됨
부경대학교 권오흠 교수님의 [c로 배우는 자료구조 및 여러 가지 예제 실습] 강의 정리입니다. 감사합니다.
https://www.youtube.com/watch?v=0FlCrw3B4mE&t=2344s
728x90
'CS > 자료구조' 카테고리의 다른 글
[자료구조 - C언어] 자료구조 제14강: Music Library Program(3) (0) | 2022.10.27 |
---|---|
[자료구조 - C언어] 자료구조 제14강: Music Library Program(1), (2) (0) | 2022.10.27 |
[자료구조 - C언어] 자료구조 제12강: 연결 리스트 - 다항식(3) (0) | 2022.10.25 |
[자료구조 - C언어] 자료구조 제12강: 연결 리스트 - 다항식(2) (0) | 2022.10.21 |
[자료구조 - C언어] 자료구조 제12강: 연결 리스트 - 다항식(1) (0) | 2022.10.20 |