ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 5주차 과제: 클래스
    Programming/Java live study 2020. 12. 24. 02:12
     

    5주차 과제: 클래스 · Issue #5 · whiteship/live-study

    목표 자바의 Class에 대해 학습하세요. 학습할 것 (필수) 클래스 정의하는 방법 객체 만드는 방법 (new 키워드 이해하기) 메소드 정의하는 방법 생성자 정의하는 방법 this 키워드 이해하기 마감일시

    github.com

    목표

    자바의 Class에 대해 학습하세요.

    학습할 것

     - 클래스 정의하는 방법

     - 객체 만드는 방법(new 키워드 이해하기)

     - 메소드 정의하는 방법

     - 생성자 정의하는 방법

     - this 키워드 이해하기

     - 과제 (optional)


    클래스, 객체

      5주차에서는 Java의 클래스 정의, 객체 생성 방법 등 클래스에 관하여 다루는 과제이다. 클래스는 간단히 말하면 객체를 만드는 틀이다. 객체라는 개념은 어떻게 생겨나게 되었는지 찾아보았다.

     

      객체를 주로 사용하는 객체 지향 프로그래밍 이전에는 코드를 위에서 부터 내려오며 실행되는 절차 지향 프로그래밍을 사용하였다. 하지만 이 절차 지향 프로그래밍은 많은 문제점을 야기 했다. 코드의 재사용성이 매우 떨어지고, 코드의 양이 길어 질 수록 유지 보수에 매우 취약해진다.

     

      이전의 개발자들은 절차 지향의 한계를 극복하기 위해 함수라는 개념을 도입하였다. 같은 로직을 가진 코드를 모아서 parameter를 전달하여 값을 반환 받는 형태로 만들었다.

     

      하지만 함수만으로도 한계가 있었다. 함수도 결국 코드의 양이 늘어나게 되면 많은 함수들이 뒤섞여 유지 보수에 어려움을 만들기 때문이다.

     

      과거에는 수학계산이나 통계 처리 과정 같은 계산의 절차가 중요하였다. 현대에 와서는 실세계에서 발생하는 일을 프로그래밍으로 구현하는 일이 많아졌다. 실세계를 절차로 표현하는 것은 한계가 있었다.

     

      이렇게 기존의 프로그래밍 방식을 보완하여 실세계를 이루는 모든 물체, 객체라는 개념이 탄생하게 되었다. 객체는 데이터와 로직이 함께 구성되어 있는 실체이다. 객체의 데이터와 로직, 즉 속성과 행위는 객체 사이의 상호 작용을 표현하는데 매우 효과적이다.

     

      절차 지향과 객체 지향을 자주 사용하는 스마트 폰에 비유해서 그림으로 표현하였다.

     

    (왼)절차지향 순서도, (오)객체지향 관계도

      객체 지향 프로그래밍은 이러한 객체를 사용하여 작성된다. 객체 지향 프로그래밍에서는 추상화, 상속, 다형성 이라는 개념을 도입하였기 때문에 재사용성이 매우 높아졌다. 또한 객체를 캡슐로 감싸서 그 내부를 보호하여 데이터에 접근할 수 없게 만든다(정보의 은닉화). 몇몇의 함수, 메소드 만이 상호작용한다.


    1. 클래스 정의하는 방법

    1.1 클래스란?

      클래스를 간단하게 정의하면 객체를 만들어 내는 틀이다. 그렇다면 객체는 무엇일까? 객체란 상태와 동작을 가진 실체이다. Java는 클래스라는 틀 혹은 설계도를 가지고 객체를 생성해서 사용한다. 이렇게 생성한 객체를 사용하는 프로그래밍 방식을 객체지향 프로그래밍이라고 한다.

     

      Java에서 클래스는 상태를 나타내는 필드(field)와 행동을 나타내는 메소드(method)로 이루어져 있다. 필드는 클래스에 포함된 변수를 의미하고, 메소드는 특정 작업을 수행하는 명령문들의 집합이다.

    1.2 클래스 정의

      객체의 개념에 대해 이해가 되었으니, 객체를 생성하기 위한 설계도를 작성해보자. Java에서 클래스를 선언하기 위해서는 class라는 키워드가 사용된다.

     

     밑의 코드는 간단하게 동물을 정의한 Animal 클래스이다.

     

    public class Animal { 
        private String name;
        private int age;
    
        public Animal() { }
        
        public Animal(String name, int age) {
            this.name = name; // java에서는 this 키워드가 생략 가능하다.
            this.age = age;
        }
    
        public String getName() {
            return this.name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return this.age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }

     

    public class Animal {
    
    }

     

     - public은 클래스에 대한 접근 권한이 public임을 의미한다. public은 다른 클래스들이 Animal 클래스를 사용하고 접근할 수 있다는 의미이다.

     - class는 Animal이 클래스임을 의미하는 키워드이다.

     - Animal은 클래스의 이름을 의미한다.

     

    field (필드)

     

    private String name;
    private int age;

     

     - 해당 클래스의 멤버변수, 즉 field를 의미한다. 객체지향에서 상태를 나타내는데 사용된다.

     - private 키워드는 public과는 다르게 자신의 field와 method를 제외하고는 접근 하거나 사용이 불가능하다.

     

    constructor (생성자)

     

    public Animal() { }
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

     

     - 클래스의 이름과 동일하면 생성자라고 한다. 생성자는 객체가 생성될 때만 호출된다. 클래스 작성 시 생성자를 생략할 수 있다. 명시되어 있지 않으면 컴파일 시 자동적으로 default 생성자가 해당 클래스에 작성된다. defualt 생성자는 아무 일도 하지 않는다.

     

    public class Exam01 {
    
        private String description;
    }

     

     description 필드만 존재하는 Exam01 클래스를 선언하였다. 

     

    package me.hyeonic.week05;
    
    public class Exam01 {
        private String description;
    
        public Exam01() {
        }
    }

     

     Exam01의 컴파일된 클래스 파일을 살펴보면 자동적으로 default 생성자가 생성된 것을 확인할 수 있다.

     

    method (메소드)

     

    public String getName() {
        return this.name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return this.age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }

     

     - method는 실행 가능한 함수이고, 행위를 표현하는데 사용한다. public은 앞서 이야기한 접근 지정자와 동일하다. public 이 후 나오는 것은 해당 method의 return 타입을 의미한다. 기본 자료형 뿐만 아니라 클래스 타입 또한 가능하다.

     

    초기화 블록 (initializer)

     

     초기화 블록을 사용하여 명시적 초기화에서 불가능한 초기화를 기능을 수행할 수 있다. 초기화 블록에는 두가지 형태의 초기화 블록을 지원한다.

     

     - 클래스 변수 초기화를 위한 클래스 초기화 블록 

     - 인스턴스 변수 초기화를 위한 인스턴스 초기화 블록 

     

    public class Exam02 {
        
        private String instanceValue; // 인스턴스 변수
        private static String staticValue; // 클래스 변수
        
        static { // 클래스 초기화 블록
            staticValue = "클래스 변수 초기화";
            System.out.println(staticValue);
        }
        
        { // 인스턴스 초기화 블록
            instanceValue = "인스턴스 변수 초기화";
            System.out.println(instanceValue);
        }
        
        public Exam02() {
            System.out.println("기본 생성자");
        }
        
        public Exam02(String instanceValue) {
            this.instanceValue = instanceValue;
        }
    
        public static void main(String[] args) {
            Exam02 exam02 = new Exam02();
        }
    }

     

    클래스 변수 초기화
    인스턴스 변수 초기화
    기본 생성자

     

    클래스 변수의 초기화 우선순위

     - 기본값 -> 필드에서 명시적 초기화 -> 클래스 초기화 블록

     

    인스턴스 변수의 초기화 우선순위

     - 기본값 -> 필드에서 명시적 초기화 -> 인스턴스 초기화 블록 -> 생성자

    1.3 접근 제어자

     public과 같은 접근 제어자는 해당 클래스의 범위를 제한하거나 허용할 수 있다. 클래스에서는 public과 default 밖에 쓸 수 없다. default는 보통 생략하여 사용한다.

    부모 클래스 멤버에 접근하는 클래스
    부모 클래스 멤버의 접근 지정자
    defualt private protected public
    같은 패키지의 클래스 O X O O
    다른 패키지의 클래스 X X X O
    같은 패키지의 자식 클래스 O X O O
    다른 패키지의 자식 클래스 X X O O

    2. 객체 만드는 방법(new 키워드 이해하기)

    2.1 객체의 생성과 레퍼런스 변수

      위의 Animal 클래스를 사용해서 객체를 생성하였다.

     

    Animal lion;
    Animal dog = new Animal();
    Animal cat = new Animal("nabi", 1);

     

    래퍼런스 변수

      Animal 클래스의 레퍼런스 변수 선언

     

    Animal lion;

     

     레퍼런스 변수는 말그대로 객체를 가리키는 참조 변수이다. Java에서 lion은 Animal 객체를 참조할 수 있는 변수이다.현재는 어떤 객체도 가리키고 있지 않기 때문에 사용할 수 없다. 해당 객체를 사용하기 위해서는 new 연산자를 통해 객체를 생성해야 한다.

     

    객체 생성

     Animal 클래스의 레퍼런스 변수 선언 및 객체 생성

     

    Animal dog = new Animal();
    Animal cat = new Animal("nabi", 1);

     

     dog와 cat 모두 앞서 언급한 생성자와 new 연산자를 통하여 객체를 생성하고 레퍼런스 변수에 각각 대입한 것이다. new 연산자를 통하여 객체가 생성되는 과정을 정리하였다.

     

     - Animal 타입의 객체 메모리 공간을 확보한다.

     - 생성자를 통하여 생성한다. 이때 작성한 생성자의 매개변수 타입에 따라 field 값을 초기화할 수 있다.

     - 대입 연산자를 통하여 레퍼런스 변수에 대입한다.

     

     각 객체를 출력하게 되면 레퍼런스 변수이기 때문에 해당 객체를 가리키는 실제 메모리 주소가 출력되는 것을 알 수 있다. lion의 경우 선언만 되어 있는 상태이기 때문에 사용할 수 없다. 혹은 아무것도 가리키지 않는 것을 의미하는 null을 대입하면 사용은 가능하다.

     

     new 키워드는 새 객체를 메모리에 할당하고 해당 메모리에 대한 참조값을 반환하여 클래스를 인스턴스화한다. 객체가 메모리에 할당되면 인스턴스라고 부른다.

     

    lion = null;
    System.out.println(lion);
    System.out.println(dog);
    System.out.println(cat);

     

    null
    me.hyeonic.week05.Animal@7f63425a
    me.hyeonic.week05.Animal@36d64342 

    더 알아보기 stack 영역과 heap 영역

     Stack 영역은 지역 변수와 파라미터 변수가 만들어진다. 객체를 선언한 레퍼런스 변수는 Stack 영역에 저장된다. heap 영역은 Java의 객체와 배열이 만들어지는 영역이다. 객체가 생성된 실체는 heap 영역에 저장된다.

     

     Stack 영역에 경우 thread (실행 흐름)마다 각각 stack segment 영역을 가진다. 그 외의 메모리 영역은 다른 thread와 공유된다. 그렇기 때문에 thread safe한 객체를 사용하기 위해서는 synchronized 클래스를 사용해야 한다.

     

    int i = 10;
    double d = 10.12;
    Person person = new Person();

     

     

    2.2 객체의 field와 method에 대한 접근

      객체의 field와 method에 접근하기 위해서는 . 연산자를 사용한다.

     

    System.out.println("dog.getName() : " + dog.getName());
    System.out.println("dog.getAge() : " + dog.getAge());
    
    System.out.println("cat.getName() : " + cat.getName());
    System.out.println("cat.getAge() : " + cat.getAge());

     

    dog.getName() : null
    dog.getAge() : 0
    cat.getName() : nabi
    cat.getAge() : 1

     

      dog의 경우 default 생성자를 통하여 생성된 객체이기 때문에 name과 age의 값이 설정되어 있지 않다. name 같은 경우 String 클래스 이기 때문에 기본적으로 null을 가리킨다. 기본 자료형 중 int는 앞서 배운 defualt 값인 0이 대입되어 있다. cat의 경우 생성자에서 field의 값을 초기화 시켜주었기 때문에 값이 잘 들어 있는 것을 알 수 있다.

    2.3 객체 배열

      객체도 기본 배열처럼 배열 선언과 생성이 가능하다.

     

    Animal[] animals; // 객체 배열에 대한 레퍼런스 변수 선언
    animals = new Animals[3]; // 크기가 3인 배열 생성. 배열의 원소는 객체에 대한 레퍼런스

     

    for (Animal animal : animals) {
        System.out.println(animal);
    }

     

    null
    null
    null

     

      현재 animals 배열의 각 객체는 아무것도 가리키고 있지 않는 상태이다. 추가적으로 객체를 대입하여 사용할 수 있다.

     생성된 배열을 사용하기 위해 초기화 해보자.

     

    for (int i = 0; i < animals.length; i++) {
        animals[i] = new Animal(i + " animal", i);
        System.out.println("name: " + animals[i].getName());
        System.out.println("age: " + animals[i].getAge());
    }

     

    name: 0 animal
    age: 0
    name: 1 animal
    age: 1
    name: 2 animal
    age: 2

    3. 메소드 정의하는 방법

    3.1 메소드의 형식

    public String getName() {
        return this.name;
    }
    
    public void setName(String name) {
        this.name = name;
    }

     

     Java에서 메소드는 접근 지정자, 리턴 타입, 메소드 이름, 매개 변수, 메소드 body 부분의 코드로 이루어져 있다.

     

     - 접근 지정자에는 public, protected, private와 생략된 경우 default로 scope에 따라 각자의 특성이 나뉜다. 간단하게 정리해보았다.

    접근 지정자 기능
    public 클래스 내부와 외부에서 모두 호출 가능하다.
    protected 클래스 내부에서 메소드 호출이 가능하다. 외부에서 호출하기 위해서는 해당 클래스를 상속받은 서브 클래스만 가능하다.
    private 클래스 내부에서만 메소드 호출이 가능하다.
    defualt 접근 지정자가 생략된 형태이고, 동일한 패키지 내의 모든 클래스에서 호출이 가능하다.

     - 리턴 타입에는 해당 메소드가 연산을 통하여 나온 값을 반환할 때의 타입을 명시한다. 간단한 예시로 String의 경우 문자열을 반환해야 하고, void는 아무 것도 반환하지 않음을 의미한다.

     - 메소드의 이름은 임의로 작성이 가능하다. Java에서는 camelCase 표기법을 따른다. 소문자로 시작해야 하고 행위를 나타내는 동사로 작성하는 것을 권장한다.

     - 메소드 코드는 메소드의 기능을 구현한 Java 코드가 들어 있다.

    3.2 값을 전달하는 call-by-value

      기본 타입의 자료형의 경우, 메소드의 인자로 값이 복사되어서 전달된다. 그렇기 때문에 원본 값은 영향을 주지 않는다.

     

    public static void increaseNumber(int a, int b) {
        ++a;
        ++b;
    }
    
    public static void main(String[] args) {
    
        int a = 1;
        int b = 2;
    
        increaseNumber(a, b);
    
        System.out.println("a : " + a);
        System.out.println("b : " + b);
    
    } 

     

    a : 1
    b : 2

     

      a와 b의 값이 1이 증가될 것을 기대 했지만 그대로 출력된다.

    3.3 레퍼런스를 그대로 전달하기 때문에 call-by-value

      메소드의 인자로 객체나 배열이 전달되는 경우에는 해당 객체나 배열을 가리키는 레퍼런스 값이 그대로 전달된다. 객체의 주소가 전달되는 것 이기 때문에 인자와 파라미터 변수가 가리키는 객체는 같은 객체가 된다.

     

    public static class NewInt {
        int number;
    }
    
    public static void increaseNumber(NewInt a, NewInt b) {
        ++a.number;
        ++b.number;
    }
    
    public static void main(String[] args) {
    
        NewInt a = new NewInt();
        NewInt  b = new NewInt();
    
        System.out.println("a : " + a.number);
        System.out.println("b : " + b.number);
    
        increaseNumber(a, b);
    
        System.out.println("a : " + a.number);
        System.out.println("b : " + b.number);
    }

     

    a : 0
    b : 0
    a : 1
    b : 1

     

      객체의 주소가 전달되었기 때문에 값이 증가하는 것을 알 수 있다. 배열의 경우에도 동일한 상황을 연출할 수 있다.

    3.4 메소드 오버로딩

      메소드 오버로딩이란 이름은 같지만 메소드의 인자의 타입과 개수, 반환 타입은 서로 다르지만 이름은 같은 메소드를 여러개 정의할 수 있다.

     

    public int getSum(int a, int b) {
        return a + b;
    }
    
    public double getSum(double a, double b) {
        return a + b;
    }
    
    public int getSum(int a, int b, int c) {
        return a + b + c;
    }

     

     메소드의 이름과 메개변수 리스트를 묶어서 메소드 시그니처라고 부른다. 컴파일러는 이러한 메소드 시그니처를 기반으로 메소드 오버로딩을 판단한다.


    4. 생성자 정의하는 방법

    4.1 생성자

     생성자는 객체가 생성될 때 초기화를 위해 실행되는 메소드의 한 종류이다. 생성자는 객체가 생성되는 시점에 자동적으로 호출된다. 메소드의 기능으로는 객체에 필요한 초기화를 수행하는 코드들이 들어있다.

     

     - 클래스의 이름과 동일하다.

     

    public Animal() {...}

     - new 연산자를 통하여 객체를 생성할 때 호출된다.

    Animal dog = new Animal();

     - 오버로딩이 가능하다.

    public Animal() {...}
    public Animal(String name, int age) {...} 

     - 반환타입을 지정할 수 없다. 하지만 값을 반환하지 않는 void와는 다르다.

    public Animal(String name, int age) {
        this.name = name; 
        this.age = age;
    }

     -  생성자는 field를 초기화하는데 매우 유용하다. 객체를 생성하면 메모리 공간은 할당되지만 field의 값을 가지고 있지 않다. 생성자 오버로딩을 통하여 특정 field들을 초기화할 수 있다.

    public Animal(String name, int age) {
        this.name = name; 
        this.age = age;
    }

     

     name과 age값을 초기화 할 수 있는 생성자이다.

    4.2 생성자 사용 시 주의사항

      클래스에 생성자를 따로 정의하지 않으면 컴파일러로 인하여 default 생성자가 생성된다. 하지만 직접 생성자를 적게되면 defualt 생성자를 만들지 않는다.

     

    public class Animal {
        public Animal(String name, int age) {...}
    }

     

    Animal dog = new Animal();

     

     그렇기 때문에 위처럼 인자를 아무것도 전달하지 않는 default 형태로 생성 한다면 정상적으로 실행되지 않는 점을 유의해야 한다. 해결방안으로는 명시적으로 default 생성자를 명시적으로 작성해주면 된다.

     

    public class Animal {
        public Animal() {...}
        public Animal(String name, int age) {...}
    }

    4.3 this()

      this()는 클래스 내에서 다른 생성자를 호출할 때 사용된다.

     

    public class Animal {
        private String name;
        private int age;
    
        public Animal() {
            System.out.println("기본 생성자");
        }
        public Animal(String name, int age) {
            this();
            this.name = name; 
            this.age = age;
        }
    }

     

    public class Main {
    
        public static void main(String[] args) {
            Animal lion = null;
            Animal dog = new Animal();
            Animal cat = new Animal("nabi", 1);
        }
    }

     

    기본 생성자
    기본 생성자

     

     

     출력이 두번 나오는 것을 알 수 있다. 인자를 가진 생성자의 this()가 실행되는 것을 알 수 있다. this()의 주의사항으로는,

     

     - this()는 생성자 코드내에서만 사용이 가능하다.

     - this()는 반드시 생성자 코드내에서 가장 먼저 사용되어야 한다.

     

    public Animal() {
        System.out.println("기본 생성자");
    }
    
    public Animal(String name, int age) {
        this.name = name; 
        this.age = age;
        this(); // 컴파일 오류가 발생한다.
    } 

    4.4 delete?

     Java에서는 C++과는 다르게 소멸자는 존재하지 않는다. 그렇기 때문에 개발자가 할당받은 메모리를 해제하기 위해서 소멸자를 작성할 필요가 없다. Java에서는 new로 할당받은 후 내부 알고리즘을 통해 사용하지 않는다고 판단한 객체를 JVM의 가비지 컬렉터(garbage collector)가 자동으로 해제시킨다.

     

     가비지 컬렉터(garbage collector)는 JVM내에서 자동으로 가비지 값들을 회수하여 메모리 공간을 늘린다. 이를 가비지 컬렉션(garbage collection)이라고 한다. 가비지 컬렉터(garbage collector)는 이를 수행하는 주체이고 JVM에서는 가비지 컬렉션 스레드(garbage collection thread)가 가비지 컬렉터(garbage collector)의 일을 담당한다.

     

    Animal dog = new Animal();
    Animal cat = new Animal();
    
    dog = cat;

     

      cat이 가리키던 객체는 더이상 아무도 참조하지 않기 때문에 가비지 콜렉터가 메모리를 회수한다.

     

    System.gc();

     

     Java에서 가비지 컬렉션(garbage collection)을 강제로 수행하기 위해서는 위 처럼 작성하면 된다. 하지만 JVM에게 제안을 하는 것이고 즉시 가비지 컬렉션(garbage collection)이 실행되는 것은 아니다.


    5. this 키워드 이해하기

     this는 객체 자신을 가리킨다.

     

    public String getName() {
        return this.name;
    }

     

      this는 현재 객체에 대한 레퍼런스이고, this.name은 자신의 field인 name에 접근한 것이다.

     

    public String getName() {
        return name;
    }

     

      동일한 이름의 변수가 존재하지 않으면 this가 생략가능하고, name은 this.name을 가리키게 된다.

     

    public void setName(String name) {
        this.name = name;
    }

     

     위의 코드의 경우 인자로 들어온 name과 혼동될 것을 우려하여 this 키워드를 사용하여 자신의 field와 인자를 구분할 수 있다.  this는 자신의 래퍼런스 그 자체를 의미한다.

     

    Animal dog = new Animal("mini", 1);
    Animal cat = new Animal("nabi", 2);
    
    dog.setAge(2);
    cat.setAge(3);

     

      dog의 this는 자신의 age를 1에서 2로 변경하고, cat 또한 자신의 age를 2에서 3으로 변경한다.


    6. 과제 (optional)

    요구 사항

     - int 값을 가지고 있는 이진 트리를 나타내는 Node 라는 클래스를 정의하세요.

     - int value, Node left, right를 가지고 있어야 합니다.

     - BinrayTree라는 클래스를 정의하고 주어진 노드를 기준으로 출력하는 bfs(Node node)와 dfs(Node node) 메소드를 구현하세요.

     - DFS는 왼쪽, 루트, 오른쪽 순으로 순회하세요.

    6.1 이진 탐색 트리 (Binary Search Tree)

     - 각 노드는 키 값을 하나씩 가지며 값은 유일하다.

     - 최상위 레벨에 root node가 존재하고, 각 node는 이진 트리이기 때문에 최대 두개의 자식을 가진다.

     - 각 node의 키 값은 자신의 왼쪽 자식 node의 키 값보다 크고, 오른쪽 자식의 키값보다 작다.

     

    이진 트리

     

      위의 전제 조건을 가지고 Node와 BinaryTree를 작성하였다. 간단한 구현을 위해 Tree에 존재하지 않는 key값만 삽입한다고 가정한다. 검색 실패시에는 null을 반환한다. 추가적인 학습을 통하여 error를 throw 할 예정이다.

     

    public class Node {
    
        private int value;
        private Node left;
        private Node right;
    
        public Node(int value) {
            this.value = value;
            this.left = null;
            this.right = null;
        }
    
        public int getValue() {
            return value;
        }
    
        public void setValue(int value) {
            this.value = value;
        }
    
        public Node getLeft() {
            return left;
        }
    
        public void setLeft(Node left) {
            this.left = left;
        }
    
        public Node getRight() {
            return right;
        }
    
        public void setRight(Node right) {
            this.right = right;
        }
    
    }

     

    public class BinaryTree {
    
        private Node root;
    
        public BinaryTree() {
            this.root = null;
        }
    
        public Node getRoot() {
            return this.root;
        }
    
        public void setRoot(Node root) {
            this.root = root;
        }
    
        public Node search(Node node, int key) { // node : tree 의 root node, key : 검색하고자 하는 key
            if (node == null || node.getValue() == key) {
                return node;
            } else if (key < node.getValue()) {
                return search(node.getLeft(), key);
            } else {
                return search(node.getRight(), key);
            }
        }
    
        public Node insert(Node node, int key) { // node : tree 의 root node, key : 삽입하고자 하는 key
            if (node == null) {
                Node root = new Node(key);
                return root;
            } else if (key < node.getValue()) {
                node.setLeft(insert(node.getLeft(), key));
                return node;
            } else {
                node.setRight(insert(node.getRight(), key));
                return node;
            }
        }
    
    }

    6.2 BFS Breadth First Search 너비 우선 탐색

     - 시작점부터 가까운 node부터 탐색한다. 즉 넓이를 우선적으로 탐색한다.

    BFS

      BFS는 Queue를 이용하여 구현한다. Queue는 FIFO(First In First Out)이다.

    6.3 DFS Depth First Search 깊이 우선 탐색

     - root node에서 최대한 깊은 node를 탐색하고 반복한다. 즉 깊이를 우선적으로 탐색한다.

    DFS

    DFS는 Stack을 이용하여 구현한다. Stack은 LIFO(Last In First Out)이다.


    references.

    황기태, 김효수 지음 생능 출판 명품 JAVA Programing

    'Programming > Java live study' 카테고리의 다른 글

    7주차 과제: 패키지  (0) 2020.12.30
    6주차 과제: 상속  (0) 2020.12.24
    4주차 과제: 제어문  (0) 2020.12.24
    3주차 과제: 연산자  (0) 2020.12.24
    2주차 과제: 자바 데이터 타입, 변수 그리고 배열  (0) 2020.12.24

    댓글

Designed by Tistory.