일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 스프링부트
- Flexbox
- 스프링 부트와 AWS로 혼자 구현하는 웹 서비스
- CS
- 개발자기술면접
- 스프링부트와 AWS로 혼자 구현하는 웹 서비스
- 기술면접
- 스프링부트 테스트코드
- 그래도일단
- 자바스크립트
- 테스트코드
- 운영체제
- 내가해냄
- AWS EC2 구현
- 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 2장
- jpa
- 어찌저찌해냄
- 트랜지스터
- 오늘도
- 스프링부트와 AWS로 혼자 구현하는 웹서비스
- Today
- Total
개발 공부
연결 리스트 - addFirst(), addLast() 본문
addFirst 메서드
: 새로운 노드를 연결 리스트의 앞부분의 추가하는 방법
1. 새로운 노드를 만든다.
2. 새로운 노드의 next가 현재 head를 가리키도록 한다.
3. head 포인터가 다시 새로운 노드를 가리키도록 한다.
public void addFirst(E obj){
Node<E> node = new Node<E>(obj);
node.next = head; // 새로 생긴 노드의 next를 기존의 노드를 가리키는 head로 설정
head = node; // 기존의 노드를 가리키는 head를 새로 생긴 노드를 가리키도록 설정
currentSize++;
}
(두 번째 줄 왜 자꾸 공백이 들어가는,,,)
위의 순서는 잘 지켜줘야 한다.
head가 가리키는 값을 node로 바꾸는 것을 먼저 한다면, 기존에 있던 객체를 가리키는 포인터가 없기 때문에 가비지 컬렉션이 일어난다.
위의 코드는 여러 노드가 아닌, 추가할 부분의 앞쪽만 신경 쓰면 되기 때문에 시간 복잡도는 1이며,
아래의 경계 조건 다섯 가지를 고려해도 문제가 없다.
https://paradiseiswhereiam.tistory.com/124
자료구조의 경계 조건
: 연결 리스트를 문제없이 사용하기 위해 고려해야 하는 것 1. 자료 구조가 비어 있을 때 ex. 만약 연결리스트의 요소 하나를 제거했을 때, 연결 리스트가 비게 된다면 어떻게 해야
paradiseiswhereiam.tistory.com
addLast 메소드
: 연결 리스트의 마지막을 가리키는 임시 포인터를 사용한다.
마지막을 가리키는 임시 포인터가 없으면 연결 리스트의 마지막 부분까지 도달하기 위해 next를 너무 많이 써야 하기 때문이다.
연결 리스트의 마지막 노드는 유일하게 next가 null을 가리키기 때문에
마지막을 가리키는 임시 포인터 tmp는 아래와 같이 작성한다.
(마지막 노드로 향해야 하기 때문에 tmp.next를 tmp로 설정)
public void addLast(E obj){
Node<E> tmp = head;
while(tmp.next != null)
tmp=tmp.next
tmp.next=node;
}
문제1. 경계 조건
head가 비어있는 경우에는 tmp가 null이 되고 이에 따라 tmp.next도 null이 되어 NullPointException 에러가 발생한다.
리스트 맨 뒤에 요소를 추가하고 싶은데 비어 있는 리스트라면, addFirst 메소드처럼 그냥 노드를 추가한다.
public void addLast(E obj){
Node<E> node = new Node<E>(obj);
if (head == null){ // head가 비어있는 경우
head=node;
currentsize++;
return;
}
Node<E> tmp = head;
while(tmp.next != null)
tmp=tmp.next
tmp.next=node;
currentsize++;
}
이때 currentSize == 0이 아니라 head == null로 조건을 건 이유는 currentSize 값을 바꿔야 하는데 실수로 바꾸지 않았을 때 문제가 생길 수 있기 때문에, 리스트가 비어 있음을 확실하게 보장 받을 수 있는 head == null로 확인한다.
문제2. 시간 복잡도
위처럼 tmp.next가 null인지 아닌지 하나하나 확인하다 보면 시간 복잡도는 O(n)이 된다.
하지만 처음부터 리스트의 마지막을 가리키는 포인터를 전역 변수로 설정한다면, 리스트의 마지막만 확인하여 시간 복잡도를 O(1)로 만들 수 있다. tail 포인터는 아래와 같이 설정한다.
public void addLast(E obj){
Node<E> node = new Node<E>(obj);
if (head == null){
head=node;
tail=node; // head 포인터뿐만 아니라 tail 포인터도 꼭 바꾸기
currentsize++;
return;
}
tail.next=node;
tail = node;
currentsize++;
}
참고
'자료구조와 알고리즘' 카테고리의 다른 글
연결 리스트 - remove(), find() (0) | 2022.08.06 |
---|---|
연결 리스트 - removeFirst(), removeLast() (0) | 2022.08.06 |
자료구조의 경계 조건 (0) | 2022.08.06 |
연결 리스트 Linked List (0) | 2022.08.05 |
시간 복잡도, 빅 오 표기법 (0) | 2022.08.04 |