리스트(List)

리스트 정의

리스트는 데이터를 순서대로 나열한 자료구조이다. 선형 리스트 또는 연걸 리스트라고도 불린다.
연결 리스트의 종류는 단일 연결 리스트, 이중연결 리스트, 원행 연결 리스트 이렇게 세가지 기본 유형이 있다.

  • 단일 연결 리스트singly-linked list: 면접관분이 “연결 리스트”라고만 말한다면 보통 단일 연결 리스트를 뜻하는 것으로
    보면 된다. 리스트에 들어가는 각 데이터 원소에는 리스트의 다음 원소에 대한 연결고리link(포인터 또는 레퍼런스)가 들어 있다.
    단일 연결 리스트의 첫 번째 원소는 리스트의 머리head라고 부른다. 단일 연결 리스트의 마지막 원소는 꼬리tail라고 부르며 연결고리는 비어 있거나 널 연결고리로 이어져 있다.

  • 이중연결 리스트doubly-linked list: 이중 연결리스트는 단일 연결 리스트의 여러 가지 단점을 극복하기 위해 만들어진 것이다.
    이중연결 시트는 각 원소마다 리스트에서 그다음에 오는 원소에 대한 연결고리 외에 그 아펭 있는 원소에 대한 연결고리도 들어 있다는 점에서 단일 연결 리스트와 다르다.

  • 원형 연결 리스트circularly-linked list: 원형 리스트는 단일 연결 리스트로 된 것도 있고, 이중 연결 리스트로 된 것도 있다.
    원형 연결 리스트에는 끝, 즉 머리나 꼬리가 없다. 원형 연결 리스트의 모든 원소에서 다음 원소를 가리키는 포인터나 레퍼런스에는 반드시 널 아닌 어떤 원소가 들어가며, 이중 연결 리스트라면 포인터/레퍼런스에도 널이 아닌 원소가 들어가야 한다. 원소가 하나밖에 없는 리스트라면 그냥 자기 자신을 가리키면 된다.

지금까지 단순 텍스트로만 설명을 해서 이해가 안되는 부분이 있을 수도 있다. 더 자세한 내용이나 부족한 내용을 학습하기 위해 연결 리스트 by 생활코딩에서 자세한 학습이 가능하다.

리스트 메서드

배열로 리스트를 구현한다. 구현하는 방법중 포인터, 커서 등이 있는데 포인터로 구현하는 리스트의 메서드를 설명토록 하겠다.

  • search(): 어떤 조건을 만족하는 노드를 검색하는 메서드.
    public E search(E obj, Comparator<? super E> c) {
    Node<E> ptr = head;							// 현재 스캔중인  노드
    
    while (ptr != null) {
      if (c.compare(obj, ptr.data) == 0) {	// 검색 성공
        crnt = ptr;
        return ptr.data;
      }
      ptr = ptr.next;							// 다음 노드를 선택
    }
    return null;								// 검색 실패
    }
    
  • addFirst(): 리시트의 머리에 노드를 삽입하는 메서드.
    public void addFirst(E obj) {
    Node<E> ptr = head;							// 삽입 전의 머리 노드
    head = crnt = new Node<E>(obj, ptr);
    }
    
  • addLast(): 리스트 꼬리에 노드를 삽입하는 메서드.
    public void addLast(E obj) {
    if (head == null)							// 리스트가 비어 있으면 
      addFirst(obj);							// 머리에 삽입
    else {
      Node<E> ptr = head;
      while (ptr.next != null)
        ptr = ptr.next;
      ptr.next = crnt = new Node<E>(obj, null);
    }
    }
    
  • removeFirst(): 머리 노드를 삭제하는 메서드.
    public void removeFirst() {
    if (head != null)							// 리스트가 비어 있지 않으면
      head = crnt = head.next;
    }
    
  • removeLast(): 꼬리 노드를 삭제하는 메서드.
    public void removeLast() {
    if (head != null) {
      if (head.next == null)					// 노드가 하나만 있으면
        removeFirst();						// 머리 노드를 삭제
      else {
        Node<E> ptr = head;					// 스캔 중인  노드
        Node<E> pre = head;					// 스캔 중인  노드의 앞쪽 노드
    
        while (ptr.next != null) {
          pre = ptr;
          ptr = ptr.next;
        }
        pre.next = null;					// pre는 삭제 후의 꼬리 노드
        crnt = pre;
      }
    }
    }
    
  • remove(): 임의의 노드를 삭제하는 메서드.
    public void remove(Node p) {
    if (head != null) {
      if (p == head)							// p가 머리 노드면
        removeFirst();						// 머리 노드를 삭제
      else {
        Node<E> ptr = head;
    
        while (ptr.next != p) {
          ptr = ptr.next;
          if (ptr == null) return;		// p가 리스트에 없습니다.  
        }
        ptr.next = p.next;
        crnt = ptr;
      }
    }
    }
    
  • removeCurrentNode(): 현재 선택한 노드를 삭제하는 메서드.
    public void removeCurrentNode() {
      remove(crnt);
    }
    
  • clear(): 모든 노드를 삭제하는 메서드.
    public void clear() {
    while (head != null)						// 노드에 아무것도 없을 때까지
      removeFirst();							// 머리 노드를 삭제
    crnt = null;
    }
    
  • next(): 선택 노드를 하나 뒤쪽으로 이동하는 메서드.
    public boolean next() {
    if (crnt == null || crnt.next == null)
      return false;							// 이동할 수 없음
    crnt = crnt.next;
    return true;
    }
    
  • printCurrentNode(): 선택 노드를 표시하는 메서드.
    public void printCurrentNode() {
    if (crnt == null)
      System.out.println("선택한 노드가 없습니다.");
    else
      System.out.println(crnt.data);
    }
    
  • dump(): 리스트의 순서대로 모든 노드를 표시하는 메서드.
    public void dump() {
    Node<E> ptr = head;
    
    while (ptr != null) {
      System.out.println(ptr.data);
      ptr = ptr.next;
    }
    }
    


리스트의 기능

리스트의 핵심적인 개념은 순서가 있는 엘리먼트의 모임이라는 것입니다.
빈 엘리먼트는 허용되지 않는다는 것도 기억해야 할 것입니다. 그리고 중복된 데이터를 허용한다는 것도 기억해두세요.
중복 허용은 배열과 리스트의 차이가 아닙니다. 배열도 중복이 허용됩니다.
중복 허용은 이후에 배울 set과 같은 데이터 스트럭쳐와의 차이라고 할 수 있습니다.
조금 이야기를 구체화합시다. 일반적으로 리스트 데이터 스트럭쳐는 아래와 같은 기능(operation)을 가지고 있습니다.

  • 처음, 끝, 중간에 엘리먼트를 추가/삭제하는 기능
  • 리스트에 데이터가 있는지를 체크하는 기능
  • 리스트의 모든 데이터에 접근할 수 있는 기능
  • 위와 같은 기능을 가지고 있고, 순서가 있으면서 중복이 허용된다면 그러한 데이터 스트럭쳐를 리스트라고 합니다.
    참조: 생활코딩 - list

리스트 정의와 사용하는 메서드 그리고 기능을 알아보았다. 리스트 관련 코드 및 실제 사용예제의 경우 자료구조와 함께 배우는 알고리즘 입문 (자바 편) - List에서 확인할 수 있다.

참조

  • 자료구조와 함께 배우는 알고리즘 입문 (자바 편)
  • 생활 코딩
 Date: July 2, 2020
 Tags:  Data Structure

Previous
⏪ 스텍(Stack)

Next
트리(Tree) ⏩