[JAVA] 단순연결리스트의 구현 - 학생부 입력 예제
2022. 4. 5. 21:02ㆍAlgorithm
연결리스트는 노드들의 연속.
노드는 해당 노드의 데이터 (항목)을 저장하는 item과,
다음 순서의 노드를 가리키는 next로 이루어져있다. (단순연결리스트 기준)
→ 노드는 item과 next를 필드로 가지는 클래스로 구현하고,
각 노드는 해당 클래스로부터 생성한 객체이다.
** 학생부 입력 예제 - 단순연결리스트로 구현 **
단순연결리스트의 노드 클래스:
//단순연결리스트의 노드 클래스
public class Node {
private String item; //데이터 (항목)을 저장
private Node next; //다음 노드의 레퍼런스 저장
//생성자 - 해당 노드의 항목 저장, 다음 노드의 레퍼런스 저장
Node(String item, Node next) {
this.item = item;
this.next = next;
}
//getter, setter
public String getItem() {
return item;
}
public Node getNext() {
return next;
}
public void setItem(String item) {
this.item = item;
}
public void setNext(Node next) {
this.next = next;
}
// 학생부에 입력된 학생의 학번을 반환하는 메소드
int getID() {
int space = item.indexOf(" ");
int ID = Integer.parseInt(item.substring(space+1));
return ID;
}
}
학생부 연결리스트 클래스:
//단순연결리스트의 클래스
// 학생부 입력을 위한 연결리스트이므로, 학생부 데이터(이름+학번)을 하나의 String으로 보았다.
import java.util.NoSuchElementException;
public class SingleList {
Node head; //가장 앞 순서의 노드
int size; //링크드리스트에 저장된 노드 수
//생성자
SingleList() {
head = null;
size = 0;
}
//탐색 메소드 - 탐색하고자 하는 노드가 링크드리스트에 저장되어있는지
int search(String target) {
Node a = head; //맨 앞 노드서부터 탐색
for (int i = 0; i < size; i++) {
if (a.getItem().equals(target)) {
return i;
}
a = a.getNext(); //다음 노드로 이동
}
return -1;
}
//빈 리스트에 노드 저장시.
void setFirst(Node newNode) {
head = newNode;
size++;
}
//삽입
void insert(Node newNode, int ID) {
Node a = head;
if (a.getID() > ID) { // 맨 앞에 삽입하는 경우
newNode.setNext(a);
head = newNode;
}
else {
for (int i = 0; i < size; i++) {
if (a.getNext() == null) {break;}
if (a.getNext().getID() > ID) {break;}
a = a.getNext();
}
if (a.getNext() == null) { // 가장 끝에 삽입하는 경우
a.setNext(newNode);
}
else { // 중간에 삽입하는 경우
newNode.setNext(a.getNext());
a.setNext(newNode);
}
}
size++;
}
//삭제 - 첫 노드
void deleteFront() {
if (size == 0) {
throw new NoSuchElementException(); // 저장된 데이터(노드) 없을 시 강제 종료.
}
head = head.getNext();
size--;
}
//삭제 - 중간 노드 or 끝 노드
void deleteMid(String target) {
if (target == null) {
throw new NoSuchElementException(); // 저장된 데이터(노드) 없을 시 강제 종료.
}
Node a = head;
for (int i = 0; i < size-1; i++) {
if (a.getNext().getItem().equals(target)) {
break;
}
a = a.getNext();
} // a 레퍼런스 변수에 target을 항목으로 갖고 있는 노드의 '직전'노 저장.
if (a.getNext().getNext() == null) { // 삭제하려는 노드가 가장 끝 노드인 경우
a.setNext(null);
}
else {
a.setNext(a.getNext().getNext());
}
size--;
}
//연결리스트의 모든 노드를 순차적으로 출력하는 메소드
void print() {
Node a = head;
for (int i = 0; i < size; i++) {
System.out.println(a.getItem());
a = a.getNext();
}
}
}
main 클래스:
// 전제: 입력받는 학생 이름의 가나다 순서는 학번의 순서와 동일하게 입력한다
// ex) 강호동 123 이승기 124 허준 129 => (O)
// 강호동 123 이승기 129 허준 124 => (X)
// 만약 학번의 순서와 가나다 순서가 다르게 입력되는 경우 (위 예의 둘째 줄), 학번의 순서를 우선으로 정렬한다.
SingleList students = new SingleList();
System.out.println("**************** 학생부 ******************");
System.out.println("이름과 학번(3자리)을 << 공백으로 구분하여 >> 입력:");
while (true) {
String st = scanner.nextLine();
if (st.equals("print")) {
students.print();
System.out.println();
}
else if (students.size == 0) { // 빈 리스트에 저장시.
students.setFirst(new Node(st, null));
}
else {
//이미 존재하는 학생을 또 입력했다면 해당 학생 노드 삭제.
if (students.search(st) == 0) { // 맨 앞 학생 삭제시
students.deleteFront();
}
else if (students.search(st) != -1) { // 중간 or 끝 학생 삭제시
students.deleteMid(st);
}
// 이미 존재하는 학생이 아니라 새로운 학생 입력시 삽입.
else {
Node newNode = new Node(st, null);
students.insert(newNode, newNode.getID());
}
}
}
실행 결과:
'Algorithm' 카테고리의 다른 글
[해시] 프로그래머스 -전화번호 목록 (2) | 2022.04.06 |
---|---|
[해시] 프로그래머스 '완주하지 못한 선수' (0) | 2022.04.06 |
[BOJ][이진탐색] 백준 2805 파이썬 (0) | 2022.04.02 |
[BOJ][정렬] 백준 1181번 파이썬 (0) | 2022.03.21 |
[BOJ][그래프] 백준 7576번 파이썬: 토마토 (0) | 2022.03.19 |