[자료구조] Linked List

Dev_Sanizzang·2021년 9월 12일
0

자료구조

목록 보기
7/13

Linked List 개념

  • 컴퓨터에 자료를 저장하는 구조의 한 종류
  • 일렬로 연결된 데이터를 저장할 때 사용된다
  • linked list는 길이가 정해져 있지 않는 데이터의 연결된 집합이다
  • 데이터를 저장할 수 있는 공간이 있으면 그 안에 다음 데이터의 주소를 가지고 있는 구조
  • 링크드 리스트는 데이터를 중간에 삽입이 쉽다.
  • 배열보다 속도는 느리다.

배열

  • 배열 방의 크기를 한번 정하면 늘리거나 줄일 수가 없다.

Linked List 단/양 방향

  • 단방향 Linked List: 한 방향으로만 이동할 수 있는 Linked List
  • 양방향 Linked List: 다음 노드의 주소를 가지고 있고 내 앞 노드의 주소도 추가로 가지고 있어서 앞 뒤로 자유롭게 다닐 수 있다.

단반향 Linked List

# 단방향 Linked List 구현
class Node{
	int data;
    Node next = null;
    
    Node(int data){
    	this.data = data
    }
    
    void append(int data){
    	Node end = new Node(data);
        Node n = this;
        while(n.next != null){
        	n = n.next;
        }
        n.next = end;
    }
    
    void delete(int data){
    	Node n = this;
        while(n.next != null){
        	if(n.next.data == data){
            	n.next = n.next.next;
            }
            else{
            	n = n.next;
            }
        }
    }
    
    void retrieve(){
    	Node n = this;
       	while(n.next != null){
        	System.out.print(n.data + "->");
            n = n.next;
        }
        System.out.println(n.data);
    }
}
# 테스트 클래스
public class SinglyLinkedList{
	public static void main(String[] args){
    	Node head = new Node(1);
        head.append(2);
        head.append(3);
        head.append(4);
        head.retrieve();
    }
}
# 결과 값
1 -> 2 -> 3 -> 4

public class SinglyLinkedList{
	public static void main(String[] args){
    	Node head = new Node(1);
        head.append(2);
        head.append(3);
        head.append(4);
        head.retrieve();
        head.delete(2);
        head.delete(3);
        head.retrieve();
    }
}
# 결과 값
1 -> 2 -> 3 -> 4
1 -> 4

Node 클래스를 감싸는 Linked List 클래스

  • 위의 Node 클래스는 살짝 취약하다 -> Header가 리스트의 첫 번째 값이면서 대표이기 때문에 어떤 프로세스가 이 Header 값이 더 이상 필요가 없어져서 삭제해 버리면 어떤 오브젝트가 아직 이 헤더에 포인터를 가지고 있는 경우 문제가 생긴다.
  • 이런 문제 해결을 위해 Node 클래스를 Linked List라는 클래스로 감싸서 Linked List의 헤더를 데이터가 아니 Linked List의 시작을 알려주는 용도로만 쓰도록 저장을 한다. 그리고 그 안에 Node클래스를 만든다.
# Node 클래스를 감싸는 Linked List 클래스 구현
class LinkedList{
	Node header;
    
    static class Node{
    	int data;
        Node next = null;
    }
    
    LinkedList(){
		header = new Node();
	}
    
    void append(int data){
    	Node end = new Node();
        end.data = d;
        Node n = header;
        while(n.next != null){
        	n = n.next;
        }
        n.next = end;
    }
    
    void delete(int data){
    	Node n = header;
        while(n.next != null){
        	if(n.next.data == data){
            	n.next = n.next.next;
            }
            else{
            	n = n.next;
            }
        }
    }
    
    void retrieve(){
    	Node n = header.next;
       	while(n.next != null){
        	System.out.print(n.data + "->");
            n = n.next;
        }
        System.out.println(n.data);
    }    
}
# 테스트 클래스
public class LinkedListNode {
	public static void main(String[] args){
    	LinkedList ll = new LinkedList();
        ll.append(1);
        ll.append(1);
        ll.append(1);
        ll.append(1);
        ll.retrieve();
        ll.delete(1);
        ll.retrieve();
    }
}
# 결과값
1 -> 2 -> 3 -> 4
2 -> 3 -> 4

Linked List 중복값 삭제

  • 정렬되어 있지 않은 Linked List의 중복값 제거(단, 버퍼를 사용하지 않음)
    Ex) 3 -> 2 -> 1 -> 2 -> 4
class LinkedList{
	Node header;
    
    static class Node{
    	int data;
        Node next = null;
    }
    
    LinkedList(){
		header = new Node();
	}
    
    void append(int data){
    	Node end = new Node();
        end.data = d;
        Node n = header;
        while(n.next != null){
        	n = n.next;
        }
        n.next = end;
    }
    
    void delete(int data){
    	Node n = header;
        while(n.next != null){
        	if(n.next.data == data){
            	n.next = n.next.next;
            }
            else{
            	n = n.next;
            }
        }
    }
    
    void retrieve(){
    	Node n = header.next;
       	while(n.next != null){
        	System.out.print(n.data + "->");
            n = n.next;
        }
        System.out.println(n.data);
    }    
    
    # Linked List 중복값 삭제함수 구현
    void removeDups(){
    	Node n = header;
        while(n != null && n.next != null){
        	Node r = n;
            while(r.next != null){
            	if(n.data == r.next.data){
                	r.next = r.next.next
                } 
                else{
                	r = r.next;
                }
            }
            n.next;
        }
    }
}
# 테스트 클래스
public class RemoveDups {
	public static void main(String[] args)[
    	LinkdeList ll = new LinkedList();
        ll.append(1);
        ll.append(3);
        ll.append(2);
        ll.append(2);
        ll.append(4);
        ll.retrieve();
        ll.removeDups();
        ll.retrieve();
    }
}
# 결과 값
1 -> 3 -> 2 -> 2 -> 4
1 -> 3 -> 2 -> 4

단방향 Linked List 뒤부터 세기

# 방법 1 
Node kthToLast(Node first, int k){
	Node n = first;
    int total = 1;
    while(n.next != null){
    	total++;
        n = n.next;
    }
    n = first;
    for(int i = 1;i < total - k + 1;i++){
		n = n.next;
	}
    return n;
}
# 방법 2. 재귀호출
class Reference{
	public int count;
}

Node kthToLast(Node n, int k, Reference r){
	if(n == null){
    	return null;
    }
    
    Node found = KthToLast(n.next, k, r);
    r.count++;
    if(r.count == k){
    	return n;
    }
    return found;
}
# 방법 3. 포인터
Node kthToLast(Node fist, int k){
	Node p1 = first;
    Node p2 = first;
    
    for(int i = 0; i < k; i++){
    	if(p1 == null) return null;
        p1 = p1.next;
    }
    
    while(p1 != null){
    	p1 = p1.next;
        p2 = p2.next;
    }
    return p2;
}
profile
기록을 통해 성장합니다.

0개의 댓글

Powered by GraphCDN, the GraphQL CDN