Search
Duplicate
😀

04. 리스트

태그
리스트
단순 연결 리스트
이중 연결 리스트
리스트
- 순서를 가진 데이터의 집합을 가리키는 추상자료형(abstract data type) - 동일한 데이터를 가지고 있어도 상관 없음 구현 방법에 따른 분류 1) 순차 리스트 : 배열을 기반으로 구현된 리스트 2) 연결 리스트 : 메모리의 동적할당을 기반으로 구현된 리스트
연결 리스트
- 자료의 논리적인 순서와 메모리 상의 물리적인 순서가 일치하지 않고, 개별적으로 위치하고 있는 각 원소를 연결하여 하나의 전체적인 자료구조를 이룬다. - 링크를 통해 원소에 접근하므로, 순차 리스트에서처럼 물리적인 순서를 맞추기 위한 작업이 필요하지 않다 - 자료구조의 크기를 동적으로 조정할 수 있어, 메모리의 효율적인 사용이 가능하다. 연결 리스트의 기본 구조 1. 노드 - 연결 리스트에서 하나의 원소를 표현하는 building block - 구성 요소 1) 데이터 필드 - 원소의 값을 저장 - 저장할 원소의 종류나 크기에 따라 구조를 정의하여 사용 2) 링크 필드 - 다음 노드의 참조값을 저장 2. 헤드 - 연결 리스트의 첫 노드에 대한 참조값을 가짐
연결 리스트 - 단순 연결 리스트 (Singly Linked List)
- 노드가 하나의 링크 필드에 의해 다음 노드와 연결되는 구조를 가진다. - 헤드가 가장 앞의 노드를 가리키고, 링크 필드가 연속적으로 다음 노드를 가리킨다. - 링크 필드가 Null인 노드가 연결 리스트의 가장 마지막 노드이다.
단순 연결 리스트의 삽입 연산 - 첫번째 노드로 삽입
- 내가 첫째가 되려면 첫째를 내 뒤에 세우면 된다!!
단순 연결 리스트의 삽입 연산 - 마지막 노드로 삽입
코드로 구현 시 위에서 설명한 첫번째 노드로 삽입 코드의 재사용으로 최초 노드 추가를 단순화 할 수 있다. 또한 마지막 노드 구하기 코드 역시 미리 구현해놓아서 재사용이 가능하다.
단순 연결 리스트의 삽입 연산 - 중간 노드로 삽입
나의 링크 ← 이전 노드의 링크 이전 노드의 링크 → 나
단순 연결 리스트의 삽입 연산 - 삭제 연산
이전 노드의 링크 ← 나의 링크 나 삭제
단순 연결 리스트 Java 구현
public class SinglyLinkedList { private Node head; // 첫번째 노드를 저장 (별도의 head가 첫번째 Node를 가리키는 형태 아님!) //첫번째 노드로 삽입하기 public void addFirstNode(String data) { // 내가 첫째가 되려면 첫째를 내 뒤에 세우면 된다. Node newNode = new Node(data, head); head = newNode; } // 마지막 노드 찾기 public Node getLastNode() { for(Node currNode = head; currNode != null; currNode = currNode.link) { // 자신의 뒤에 아무도 없으면 자신이 막내 if(currNode.link == null) return currNode; } return null; } // 마지막 노드로 삽입하기 public void addLastNode(String data) { if(head == null) {// 공백리스트 addFirstNode(data); return; } Node lastNode = getLastNode(); lastNode.link = new Node(data, null); } // 선행 노드를 기준으로, 그 노드 뒤에 data를 가지는 노드 삽입 public void insertAfterNode(Node preNode, String data) { if(preNode == null) { System.out.println("선행노드가 없어 삽입이 불가능합니다."); return; } // 나의 링크를 이전 노드의 링크(다음노드)로 // 선행노드의 링크를 지금 만드는 Node로 바꾼다. Node newNode = new Node(data, preNode.link); preNode.link = newNode; } // data를 데이터로 갖고 있는 처음 만나는 노드 리턴 public Node getNode(String data) { for(Node currNode = head; currNode != null; currNode = currNode.link) { if(currNode.data.equals(data)) { return currNode; } } return null; } // target의 이전노드 찾기 // 특정 Node의 링크값이 나를 가리키고 있으면 -> 그것이 이전 노드 public Node getPreviousNode(Node target) { for(Node currNode = head; currNode != null; currNode = currNode.link) { if(currNode.link == target) { return currNode; } } return null; } // data를 가지고 있는 첫번째 노드 찾아서 삭제 public void deleteNode(String data) { Node targetNode = getNode(data); if(targetNode == null) { System.out.println("삭제할 노드가 없어서 삭제가 불가능합니다."); return; } Node preNode = getPreviousNode(targetNode); if(preNode == null) { // 이전 노드가 없다 -> target이 head인 상황 head = targetNode.link; }else { // target이 첫번째 노드가 아닌 상황 preNode.link = targetNode.link; } targetNode.link = null; } public void printList() { System.out.print("L = ( "); for(Node currNode = head; currNode != null; currNode = currNode.link) { System.out.print(currNode.data + " "); } System.out.println(" ) "); } }
Java
복사
이중 연결 리스트
- 양쪽 방향으로 순회할 수 있도록 노드를 연결한 리스트 - 두개의 링크 필드와 한 개의 데이터 필드로 구성 이중 필드로 구성되어 있기에 단일 연결 리스트보다 삽입, 삭제 연산 시 추가 동작 구현이 필요하다. ex) 이전 노드 - 삽입 - 다음 노드 1. 나의 next ← 이전 노드의 next 2. 나의 prev ← 다음 노드의 prev 3. 이전 노드의 next ← 나 4. 다음 노드의 prev ← 나