큐(Queue)


1. 큐(Queue)

  • 큐는 자료 구조에 들어있는 요소 중에서 가장 먼저 삽입한 요소를 꺼냄.
    • enqueue는 요소를 큐에 삽입
    • dequeue는 요소를 큐에서 가장 먼저 삽입한 요소를 꺼냄
  • 먼저 삽입된 요소부터 순서대로 꺼내는 규칙을 FIFO(first-in first-out)라고 함

 

2. 큐(Queue) 구현

2.1 큐(Queue) Interface

public interface Queue<T> {
	
    // 큐(Queue)에 Node 삽입
	void enqueue(T value);
	
    // 큐(Queue)의 사이즈를 반환
	int size();
	
    // 큐(Queue)가 비어있는지 true/false 반환
	boolean isEmpty();
	
    // 큐(Queue)의 첫번째 Node의 값을 반환하고 Node를 삭제
	T dequeue();
	
    // 큐(Queue)의 첫번재 Node의 값을 반환
	T peek();
	
    // 입력받은 값이 큐(Queue)에 존재하는지 true/false를 반환
	boolean contains(T string);
}

 

2.2 큐(Queue)의 메소드 구현

2.2.1 큐의 Node 정의

// Queue의 Node를 정의
    private static class Node<T>{
		private T data;
		
		private Node<T> next;
		
		public Node(T data) {
			this.data = data;
			this.next = null;
		}
	}

2.2.2 enqueque() 메소드 구현

// 큐에 Node를 삽입하는 메소드
    @Override
	public void enqueue(T value) {
		
		Node<T> newNode = new Node<T>(value);
		
		if(isEmpty()) {
			front = newNode;
			rear = newNode;
		}else {
			rear.next = newNode;
			rear = newNode;
		}
		
		size++;
	}

2.2.3 size() 메소드 구현

// 큐의 size를 반환하는 메소드
    @Override
	public int size() {
		return size;
	}

2.2.4 isEmpty() 메소드 구현

// queue가 비어있으면 true를 반환, 비어있지 않으면 false를 반환하는 메소드	
    @Override
	public boolean isEmpty() {
		return (this.size == 0);
	}

2.2.5 dequeue() 메소드 구현

// 큐의 첫번째 Node의 값을 반환하고 Node를 삭제하는 메소드
    @Override
	public T dequeue() {
		if(isEmpty()) {
			throw new RuntimeException("스택이 비어있습니다.");
		}else {
			Node<T> deNode = front;
			
			front = front.next;
			size--;
			
			return deNode.data;
		}

	}

2.2.5 peek() 메소드 구현

// 큐의 첫번째 Node의 값을 반환하는 메소드
    @Override
	public T peek() {
		if(isEmpty()) {
			throw new RuntimeException("스택이 비어있습니다.");
		}
		
		return front.data;
	}

2.2.6 contains() 메소드 구현

// 입력받은 값이 큐에 존재하면 true, 존재하지 않으면 false를 반환하는 메소드
	@Override
	public boolean contains(T string) {
		Node<T> current = front;
		
		while(current != null) {
			if(current.data.equals(string)) {
				return true;
			}
			current = current.next;
		}
		
		return false;
	}

2.2.7 toString() 메소드 구

// 큐에 존재하는 모든 Node의 값을 출력하는 메소드
    @Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		Node<T> current = front;
		
		sb.append("[");
		
		while(current != null) {
			sb.append(current.data + ", ");
			current = current.next;
		}
		
		if(sb.lastIndexOf(",") != -1) {
			sb.replace(sb.lastIndexOf(","), sb.length(), "]");
		}else {
			sb.append("]");
		}
		
		return sb.toString();
	}

 

3. 큐(Queue) 테스트

3.1 size() & isEmpty()  테스트

// 큐 생성 후, size()메소드와 isEmpty()메소드 테스트
Queue<String> queue = new ArrayListQueue<>(5);
		
System.out.println(queue);				
System.out.println(queue.size());
System.out.println(queue.isEmpty());

3.2 enqueue()  테스트

// enqueue() 테스트
queue.enqueue("딸기");
queue.enqueue("포도");
queue.enqueue("망고");
queue.enqueue("수박");
queue.enqueue("사과");
		
System.out.println(queue);
System.out.println(queue.size());	// Node가 5개 삽입되었기 때문에 5를 반환
System.out.println(queue.isEmpty());	// Node가 삽입되었기 때문에 false를 반환

 

3.3 dequeue()  테스트

// dequeue() 테스트
System.out.println(queue.dequeue());
System.out.println(queue.dequeue());
	
System.out.println(queue);
System.out.println(queue.size());	// Node 2개를 삭제했기 때문에 3을 반환
System.out.println(queue.isEmpty());

 

3.4 peek()  테스트

// peek() 테스트
System.out.println(queue.peek());
System.out.println(queue);
System.out.println(queue.size());	//peek()는 Node의 값만 반환하고 삭제하지 않기 때문에 3을 반환
System.out.println(queue.isEmpty());

3.5 contains()  테스트

// contains() 테스트
System.out.println(queue);
System.out.println(queue.contains("망고"));	// true를 반환
System.out.println(queue.contains("딸기"));	// false를 반환

웹 통신 개요


1. 웹 서버(Web Server)

  • 웹에서 서버 기능을 수행하는 프로그램으로 HTML 문서나 JPG, PNG 같은 이미지를 HTTP 프로토콜을 통해 웹 브라우저에 제공하는 서버
  • 서버 내부의 이미 만들어져 있는 정적인 요소들을 화면에 제공하는 역할
  • 웹 서버의 종류

 

2. 웹 애플리케이션 서버(Web Application Server)

  • 웹 서버가 할 수 없는 다양한 비즈니스 로직을 수행하고 동적인 페이지를 만들어 제공하는 서버
  • 웹 애플리케이션 서버는 웹 서버와 컨테이너로 구성
  • 웹 애플리케이션 서버의 종류

 

3. 컨테이너

3.1. 서블릿 컨테이너

  • 서블릿 컨테이너는 클라이언트의 요청에 따라 서블릿을 수행하는 역할

3.2. JSP 컨테이너

  • JSP 컨테이너는 JSP를 서블릿으로 변환하는 역할
  • JSP 컨테이너는 JSP 파일을 서블릿으로 변환 및 컴파일까지만 담당하는 프로그램이며, 변환된 서블릿의 수행은 서블릿 컨테이너가 담당

톰캣(Tomcat) 설치


1. Apache Tomcat Download

  • Eclipse에서 바로 실행시 java 환경변수 설정이 필요없음
  • local에서 실행시 java 환경변수를 설정해야 함

Apache Tomcat Download : https://tomcat.apache.org/

 

Apache Tomcat® - Welcome!

The Apache Tomcat® software is an open source implementation of the Jakarta Servlet, Jakarta Pages, Jakarta Expression Language, Jakarta WebSocket, Jakarta Annotations and Jakarta Authentication specifications. These specifications are part of the Jakarta

tomcat.apache.org

download

 

2. Apache Tomcat 폴더 압축 풀기

원하는 경로에 압출 풀기

 

3. Workspace 설정

File > Switch Workspace > other
launch

 

4. Encoding

Window > Preferences
utf-8로 인코딩
나머지 4개도 utf-8로 인코딩

 

 

5. JDK 설정

Window > Preferecnes
자신이 가지고 있는 java version으로 설정
다운로드 받은 jdk 폴더 add
next
다운로드 받은 jdk 폴더 Finish > apply

 

6. Tomcat 연결

Tomcat 추가
Download 받은 Tomcat version 클릭 후 Next
Tomcat을 Download 받은 경로를 지정해주고 JRE 버전 설정 후 Finish
Apply and Close
설정한 Tomcat 서버 생성
Download 받은 Tomcat의 버전 클릭 후 Finish
Tomcat 연동!

7. 연결한 Tomcat 확인

클릭
8080 포트
체크 후 저장
우클릭 start
정상적으로 실행되면 완료

그리디(Greedy)


1. 그리디(Greedy)

  • 그리디는 탐욕스러운 또는 욕심이 많은이라는 뜻
  • 그리디는 문제를 해결하는 데 있어 각 단계에서 가장 최적이라고 생각되는 선택을 하는 알고리즘
  • 그리디로 문제를 해결하는 접근 방식은 전체적으로 최적의 해결책을 보장하지는 않지만, 많은 경우에 매우 좋은 근사해를 제공하거나, 특정 문제에서는 최적의 해결책을 제공할 수 있음

 

2. 그리디 알고리즘의 장단점

  • 간단하고 구현이 용이
  • 특정 문제에서는 최적의 해결책을 보장
  • 일부 문제에서는 최적의 해결책을 보장하지 못함

 

3. 그리디 알고리즘 문제

3.1 거스름돈 문제 : 가장 적은 수의 동전으로 거스름돈을 주는 문제

public class GreedyExample {
	// 1. 거스름돈 문제
	// -가장 적은 수의 동전으로 거스름돈을 주는 문제
	public static int minCoins(int[] coins, int amount) {
		
		int count = 0;				// 동전 개수
		
		Arrays.sort(coins);			// 동전 금액을 오름차순으로 정렬
		
		for(int i = coins.length - 1; i >= 0; i--) {
			count += amount / coins[i];
			
			System.out.printf("%d 동전은 %d개 필요합니다.\n", coins[i], amount / coins[i]);
			
			amount %= coins[i];
		
		}
		
		System.out.println("총 사용한 동전의 개수 : " + count);
		
		return count;
		
	}
	
}

3.2 활동 선택 문제 : 최대한 많은 활동을 선택할 수 있는 활동의 최대 개수를 구하는 문제

public class GreedyExample {
	// 2. 활동 선택 문제
	//	- 최대한 많은 활동을 선택할 수 있는 활동의 최대 개수를 구하는 문제
	public static int maxActivities(int[][] activities) {
		int count = 1;
		
		// 1. 활동을 종료시간 기준으로 정렬
		Arrays.sort(activities, Comparator.comparingInt(values -> values[1]));

		
		// 2. 첫번째 활동을 선택
		int laststartTime = activities[0][0];
		int lastEndTime = activities[0][1];
		
		System.out.printf("활동 시작 시간 : %d, 활동 종료 시간 : %d \n", laststartTime, lastEndTime);
		
		// 3. 현재 선택된 활동 종료 시간 이후에 시작하는 활동이 없을 때가지 반복을 수행
		for(int i = 1; i < activities.length; i++) {
			if(lastEndTime <= activities[i][0]) {
				
				laststartTime = activities[i][0];
				lastEndTime = activities[i][1];
				
				System.out.printf("활동 시작 시간 : %d, 활동 종료 시간 : %d \n", laststartTime, lastEndTime);
				
				count++;
			}
		
		}
		
		return count;
	}
}

스택(Stack)


1. 스택(Stack)

  • 스택은 자료 구조에 들어있는 요소 중에서 마지막에 삽입한 요소를 꺼
    • push는 요소를 스택에 삽입
    • pop은 요소를 스택에서 마지막에 삽입한 요소를 꺼냄
  • 먼저 들어간 것이 마지막에 나오는 규칙을 LIFO(list-in first-out)라고 함

 

2. 스택(Stack) 구현

2.1 스택(Stack) Interface

package com.beyond.palindromes.structure;

public interface Stack<T> {
	
    // 스택에 노드 추가
	void push(T value);
	
    // 스택의 size 반환
	int size();
	
    // 스택이 비어있는지에 대해 true/false 반환
	boolean isEmpty();

	// 스택의 마지막 노드 값 출력 후 제거
	T pop();

	// 스택에 입력받은 값이 존재하는지 true/false 반환
	boolean contains(String string);

	// 스택의 마지막 노드 값 반환
	T peek();

}

 

2.2 스택(Stack)의 메소드 구현

2.2.1 스택의 Node

	// 스택의 Node
    private static class Node<T>{
		private T data;
		private Node<T> next;
		
		public Node(T data) {
			this.data = data;
			this.next = null;
		}
	}

2.2.2 push() 메소드

	// 스택에 node를 추가하는 메소드
    @Override
	public void push(T value) {
		Node<T> newNode = new Node<>(value);
		
		newNode.next = top;
		top = newNode;
		
		size++;
	}

2.2.3 size() 메소드

	// 스택의 size를 반환하는 메소드
    @Override
	public int size() {
		return this.size;
	}

2.2.4 isEmpty() 메소드

	// 스택이 비어있다면 true, 비어있지 않다면 false를 반환하는 메소드
    @Override
	public boolean isEmpty() {
		return top==null;
	}

2.2.5 pop() 메소드

	// 스택의 마지막 Node의 값을 반환하고 Node를 삭제하는 메소드
    @Override
	public T pop() {
		if(isEmpty()) {
			throw new RuntimeException("스택이 비어있습니다.");
		}
		
		T value = top.data;
		
		top = top.next;
		
		size --;
		
		return value;
	}

2.2.6. contains 메소드

	//입력받은 값이 스택에 존재한다면 true, 존재하지 않는다면 false를 반환하는 메소드
    @Override
	public boolean contains(String string) {
		Node<T> current = top;
		
		while(current != null) {
			if(current.data.equals(string)) {
				return true;
			}
			
			current = current.next;
		}
	
		return false;
	}

2.2.7. peek() 메소드

	// 스택의 마지막 노드의 값을 반환하는 메소드
    @Override
	public T peek() {
		if(isEmpty()) {
			throw new RuntimeException("스택이 비어있습니다.");
		}
		return top.data;
	}

2.2.8. toString() 메소드

	// 스택에 존재하는 모든 Node의 값을 출력하는 메소드
	@Override
	public String toString() {
		Node<T> current = top;
		StringBuilder sb = new StringBuilder();
		
		sb.append("[");
		
		while(current != null) {
			sb.append(current.data + ", ");
			
			current = current.next;
		}
		
		if (sb.lastIndexOf(",") != -1) {
			sb.replace(sb.lastIndexOf(","), sb.length(), "]");			
		} else {
			sb.append("]");		
		}

		return sb.toString();
	}

 

3. 스택(Stack) 테스트

3.1 size() & isEmpty()  테스트

// 스택 생성 후, size()메소드와 isEmpty()메소드 테스트
Stack<String> stack = new LinkedListStack<>();
		
System.out.println(stack);			// toString()을 재정의 하여 스택의 모든 Node의 값을 출력
System.out.println(stack.size());
System.out.println(stack.isEmpty());

3.2 peek()  테스트

// push() 테스트
stack.push("딸기");
stack.push("포도");
stack.push("바나나");
		
System.out.println(stack);
System.out.println(stack.size());		// 스택에 3개의 Node를 삽입하였으므로 3을 반환
System.out.println(stack.isEmpty());		// 스택에 Node를 삽입하였으므로 false
System.out.println();

3.3 pop()  테스트

// pop() 테스트
System.out.println(stack.pop());	// stack은 LIFO이므로 "바나나"를 반환하고 노드를 삭제
		
System.out.println(stack);
System.out.println(stack.size());
System.out.println(stack.isEmpty());

3.4 contains()  테스트

// contains()메소드 테스트
System.out.println(stack);
System.out.println(stack.contains("딸기"));
System.out.println(stack.contains("바나나"));

3.5 peek() 테스트

// peek() 메소드 테스트
System.out.println(stack.peek());

System.out.println(stack.size());		// peek()는 값만 반환하고 삭제하지 않으므로 size는 그대로
System.out.println(stack.isEmpty());
System.out.println();

1. 배열(Array)

  • 배열은 같은 타입의 원소들을 효율적으로 관리할 수 있는 자료 구조
  • 배열은 하나의 변수 이름으로 동일한 타입의 데이터를 그룹화하여 관리 가능
  • 배열의 요소를 일렬로 나열하고 각 요소에 인덱스를 사용하여 원하는 데이터에 접근 가능

 

2. 연결 리스트(Linked List)

  • 배열의 약점인 삽입과 삭제 작업에 강한 자료 구조로 연결 리스트가 있음
  • 연결 리스트는 각 요소를 포인터라고 부르는 화살표에 의해 한 줄로 나열한 것

  • 연결 리스트의 종류
    • 단방향 연결 리스트는 각 노드를 연결하는 포인터가 어느 한쪽 방향이 되도록 한 것
    • 양방향 연결 리스트는 각 노드를 연결하는 포인터가 양방향이 되도록 한 것

 

3. 단순 연결 리스트(Singly-Linked List)

 

3.1 단순 연결리스 구현

  • List Interface
// List 인터페이스

public interface List<T> {
	
	// 첫번째에 노드 삽입
	void addFirst(T data);
	
	// 마지막에 노드 삽입
	void addLast(T data);
	
	// 노드 삽입
	void add(int index, T data);
	
	// 리스트 사이즈
	int size();
	
	// 입력받은 인덱스 노드의 값 반환
	T get(int index);
	
	// 입력받은 값의 node가 있는지 true, false 반환
	boolean contains(T data);
	
	// 첫번째 노드 삭제
	void removeFirst();
	
	// 마지막 노드 삭제
	void removeLast();
	
	// 입력받은 인덱스 노드 삭제
	void remove(int index);
	
	// 입력받은 데이터에 해당하는 노드 삭제
	void remove(T data);
}
  • Node 정의 
	// 노드 클래스 정의
	private static class Node<T> {
		private T data; // 노드가 저장하는 데이터
		
		private Node<T> next; // 다음 노드를 가리키는 참조

		public Node(T data) {
			this.data = data;
			this.next = null;
		}
	}

  • 0 번째 Node 삽입하는 메소드
	public void addFirst(T data) {
		Node<T> newNode = new Node<>(data);
		
		if (head == null) {
			head = newNode;
		} else {
			newNode.next = head;
			head = newNode;
		}
		
		size++;
	}

  • 마지막 Node 삽하는 메소드
	// 마지막 값 삽입
	@Override
	public void addLast(T data) {
		Node<T> newNode = new Node<>(data);
		
		if (head == null) {
			head = newNode;
		} else {
			Node<T> lastNode = this.search(size - 1);
			
			lastNode.next = newNode;
		}
		
		size++;
	}

  • 입력받은 인덱스에 Node를 삽입하는 메소드
	public void add(int index, T data) {
		if(index < 0 || index > size){
			throw new IndexOutOfBoundsException();
		}
		
		if(index == 0) {
			this.addFirst(data);
			
			return;
		}
		
		if(index == size) {
			this.addLast(data);
			
			return;
		}
		
		Node<T> newNode = new Node<>(data);
		Node<T> prevNode = this.search(index - 1);
		
		newNode.next = prevNode.next;
		prevNode.next = newNode;
		
		size++;
		
	}

  • 현재 List의 Size를 반환하는 메소드
	@Override
	public int size() {
		
		return this.size;
	}

  • 입력받은 인덱스 노드의 값 반환하는 메소드
	@Override
	public T get(int index) {
		if(index < 0 || index >= size) {
			throw new IndexOutOfBoundsException();
		}
		
		return this.search(index).data;
	}

  • 입력받은 값의 node가 있는지 true, false 반하는 메소드
	@Override
	public boolean contains(T data) {
		Node<T> current = head;
		
		while(current != null) {
			if(current.data.equals(data))
				return true;
			
			current = current.next;
			
		}
		return false;
	}

  • 0번째 인덱스의 Node 삭제하는 메소드
	@Override
	public void removeFirst() {
		if(head ==null) {
			return;
		}else {
			Node<T> first = head;
			
			head = first.next;
			
			first.data = null;
			first.next = null;
			
			size--;
		}
		
	}

  • 마지막 인덱스의 Node를 삭제하는 메소드
	@Override
	public void removeLast() {
		if(head == null) {
			return;
		}else if((size - 2) <= 0){
			this.removeFirst();
			
			return;

		}else {
			Node<T> lastPrevNode = this.search(size-2);
			
			lastPrevNode.next.data = null;
			lastPrevNode.next = null;
			
			size --;
		}
	}

  • 입력받은 인덱스의 Node를 삭제하는 메소드
	public void remove(T data) {
		
		Node<T> current = head;
		
		if(current == null) {
			return;
		}
		
		if(current.data.equals(data)) {
			this.removeFirst();
			
			return;
		}
		
		for(int i = 0; i < size - 1; i++) {
			if(current.next.data.equals(data)) {
				Node<T> nextNode = current.next;
				
				current.next = nextNode.next;
				nextNode.data = null;
				nextNode.next = null;
				
				size--;
				
				break;
				
			}
			
			current = current.next;
		}
		
	}

  • 입력받은 값의 List의 인덱스를 통해 값을 반환하는 메소드
	private Node<T> search(int index) {
		Node<T> node = head;
		
		for (int i = 0; i < index; i++) {
			node = node.next;
		}		
		
		return node;
	}

  • List를 출력하는 메소드
	@Override
	public String toString() {
		Node<T> current = head;
		StringBuilder sb = new StringBuilder();
		
		sb.append("[");
		
		while(current != null) {
			sb.append(current.data + ", ");
			
			current = current.next;
		}
		
		if (sb.lastIndexOf(",") != -1) {
			sb.replace(sb.lastIndexOf(","), sb.length(), "]");			
		} else {
			sb.append("]");		
		}

		return sb.toString();
	}

 

3.2 단순 연결리스 테스트

  • SinglyLinkedList 테스트
		List<String> list = new SinglyLinkedList<>();
		
		System.out.println(list);
		System.out.println("size : " + list.size());
		System.out.println();


  • addFirst() 메소드 테스트
		list.addFirst("딸기");
		
		System.out.println(list);
		System.out.println("size : " + list.size());
		System.out.println();


  • addLast() 메소드 테스트
		list.addLast("포도");
		list.addLast("키위");
		
		System.out.println(list);
		System.out.println("size : " + list.size());
		System.out.println();

 


  • add() 메소트 테스트
		list.add(0, "수박");
		list.add(4, "바나나");
		
	
		System.out.println(list);
		System.out.println("size : " + list.size());
		System.out.println();


  • get() 메소드 테스트
		System.out.println(list.get(0));
		System.out.println(list.get(1));
		System.out.println(list.get(3));
		System.out.println(list.get(6));
		System.out.println();


  • removeFrist() 메소드 테스트
		list.removeFirst();
		
		System.out.println(list);
		System.out.println("size : " + list.size());
		System.out.println();

 


  • removeLast() 메소드 테스트
		list.removeLast();
		
		System.out.println(list);
		System.out.println("size : " + list.size());
		System.out.println();


  • remove() 메소드 테스트 (입력값 인덱스)
		list.remove(1);
		
		System.out.println(list);
		System.out.println("size : " + list.size());
		System.out.println();


  • remove() 메소드 테스트 (입력값 값)
		list.remove("키위");
		System.out.println(list);
		System.out.println("size : " + list.size());
		System.out.println();


  • contains() 메소드 테스트
		System.out.println(list);
		
		System.out.println(list.contains("딸기"));
		System.out.println(list.contains("두리안"));
		System.out.println(list.contains("바나나"));
		System.out.println(list.contains("참외"));
		System.out.println();

'자료구조' 카테고리의 다른 글

[자료구조] 그래프(Graph)  (0) 2024.06.28
[자료구조] 트리(Tree)  (0) 2024.06.28
[자료구조] 해시 테이블(Hash Table)  (0) 2024.06.28
[자료구조] 큐(Queue)  (0) 2024.06.28
[자료 구조] 스택(Stack)  (0) 2024.06.20

+ Recent posts