linked list(2)
연결 리스트의 응용
연결 리스트의 종류
-
단순 연결 리스트: 하나의 링크만 있고, 각각의 노드의 링크는 후행 노드만을 가리키는 구조
특정 노드의 후행 노드는 쉽게 접근 가능하지만 특정 노드의 선행 노드에 대한 접근은 헤드 노드부터 재검색해야하는 문제점이 발생
-> 포인터를 두 개로 해서 해결?
:프로그래밍 코드가 비효율적이게 될 수 있음.
-
이중 연결 리스트
코드의 변경을 최소화 -> Llink만 추가해주면, 선행 노드도 가르킬 수 있음.
-
이중 연결 리스트: 특정 노드는 선행 노드를 가르키는 링크와 후행 노드를 가르키는 링크를 가진다.
-> 특정 노드에서 선행 노드와 후행 노드에 간단한 프로그램 코드를 통해 접근 가능
-
원형 이중 연결 리스트
- 데이터를 쉽게 추가하고 삭제할 수 있다는 장점
- 연결 리스트는 마지막 노드의 링크 필드는 언제나 null값
- 리스트의 마지막 원소 뒤에는 아무 원소도 없기 때문에 연결 리스트의 마지막 노드의 링크필드는 언제나 Null
- 그래서 마지막 노드의 링크 필드를 활용하면서도 프로그래밍 성능에 도움이 되도록 하기 위해 원형 연결 리스트가 제안
*참조: null값이란 영역이 할당되어있으나 그 안에 데이터가 없는 상태를 의미
typedef struct ListNode{ // 원형 연결 리스트의 노드 구조 정의
int data;
struct ListNode*link;
} listNode;
typedef struct { // 원형 연결 리스트의 헤드 노드 구조 정의
listNode*head;
} linkedList_h;
linkedList_h* createLinkedList_h(void) { // 원형 연결 리스트의 헤드 노드 생성
linkedList_h*H;
H = (linkedList_h*)malloc(sizeof(linkedList_h));
H -> head = NULL;
return H;
}
우선적으로 헤더값은 0
삽입연산👇
void addFirstNode(linkedList_h*H, int x) {
// 원형 리스트 첫 번째 노드 삽입 연산, x값은 100으로 가정
listNode*tempNode;
listNode*NewNode;
NewNode = (listNode*)malloc(sizeof(listNode));
NewNode -> data = x;
NewNode -> link = NULL;
}
원형 연결 리스트의 노드 삽입👇
void addFirstNode(linkedList_h*H, int x) {
if(H -> head == NULL) { //현재 리스트가 공백인 경우
H -> head = NewNode;
NewNode -> link = NewNode;
return;
}
tempNode = H -> head; // 호출 값으로 포인터를 주는 것
while(tempNode -> link != H -> head) // null이 아닌지 check (head노드가 마지막 노드를 찾는 과정 )
tempNode = tempNode -> link;
NewNode -> link = tempNode -> link;
tempNode -> link = NewNode;
H -> head = NewNode;
}