자료구조(Data Structure)
자료구조 종류
- 순차 리스트
- 배열 / 행렬 / 레코드
- 스택 / 큐 / 데크
- 연결리스트
- 단일 연결 리스트
- 원형 연결 리스트
- 이중 연결 리스트
- 트리
- 일반 트리
- 이진 트리
순차 리스트
- 각 자료가 메모리 중에서 서로 이웃해 있는 구조
선형 구조
라고도 함- 메모리에 연속적으로 저장
- 종류
- 배열 / 행렬 / 레코드
- 스택 / 큐 / 데크
배열
- 크기와 데이터형이 같으며 동일한 이름을 갖는 원소들의 연속적 저장공간
- 배열의 원소는 메모리 내에서 연속적으로 순서대로 저장
- 각 배열의 원소는 첨자(인덱스 [0]부터 시작)로 구별
레코드
- 서로 다른 데이터 형태와 크기로 구성되어 있는 데이터 구조
- 이질적 구조
- ex)
- 어떤 사람에 관한 자료들인 이름, 주민등록번호, 주소 등과 같이 서로 관계있는 여러 필드를 한 개의 조로 묶어서 구성
- 배열과의 차이점
- 배열: 데이터 원소의 크기와 데이터 형태 동일
- 레코드: 데이터 원소의 크기와 데이터 형태 서로 다름
스택 (Stack)
- 쌓아 올린 더미를 의미
- 선형 리스트 구조의 특별한 형태
- 리스트 내의 데이터 삽입과 삭제가 Top이라고 하는 한쪽 끝에서만 일어나는 데이터 구조
- 데이터 구조에서는 기억 장치에 데이터를 일시적으로 쌓아 두었다가 필요할 때 꺼내서 사용할 수 있는 주기억장치(메모리)나 레지스터의 일부를 할당하여 사용하는 임시적인 기억을 말함
- 푸시(push) / 팝(pop)의 이름으로 가장 마지막에 삽입한 데이터를 제일 먼저 삭제
LIFO(Last-In First-Out)
/후입선출
방식
- n: 스택 크기
- 스택에 저장할 수 있는 최대 노드의 수
- TOP: top point
- 스택에 대한 삽입과 삭제가 이루어지는 위치
- 가장 최근에 입력된 항목의 위치를 가리키는 포인터
- 출력 우선 순위가 가종 높은 원소를 가리키는 포인터
- 초기에 TOP은 0부터 시작
- 주의!!
- 배열로 스택 구현 시 배열 첨자가 0부터 시작하므로 TOP은 -1로 초기화
- BOTTOM
- TOP의 반대쪽으로 노드의 입출력 불가
- PUSH: 삽입
- 스택에 새로운 노드 입력
- TOP = TOP + 1
- POP: 삭제
- 스택에서 노드 삭제
- TOP = TOP - 1
- 오버플로우(Overflow)
- 스택이 가득 차있을 때 (TOP == n) 새로운 노드가 생기면 스택에 더 이상 삽입을 할 수 없는 경우
- TOP > n
- Full (스택에 삽입 전에 Overflow가 발생하는지(스택이 가득 차있는지) 확인:
isfull()
)
- 언더플로우(underflow)
- 스택이 비어있을 때(TOP == 0) 노드의 삭제가 일어나서 더 이상 삭제를 할 수 없는 경우
- TOP < 0
- Empty (스택에서 노드 삭제 전에 underflow가 발생하는지(스택이 비어있는지) 확인:
isEmpty()
)
스택에서 사용되는 연산
- 삽입(push)
if TOP == n then overflow exist
TOP = TOP + 1
stack[TOP] <- insert_data
- 삭제 (pop)
if TOP = 0 then underflow exist
deleted_data <- stack[TOP]
TOP = TOP -1
스택의 이용
- 서브 프로그램의 복귀 주소(return address) 보관
- 산술식 표현 : a + b
- Java 프로그램에서 메서드 호출하고 실행할 때 스택 사용
힙 영역
- JVM 시작할 때 생성
- 객체 / 배열 저장
- 사용되지 않는 객체는 Garbage Collector가 자동 제거
JVM 스택
- 스레드 별 생성
- 메서드 호출할 때마다 프레임(Frame)을 스택에 추가 (PUSH)
- 메서드 종료하면 프레임 제거 (POP)
- 프레임 내부의 로컬 변수 스택에 변수 저장
- 변수에 값이 저장될 때 변수 생성
연습문제 - Stack
- 스택(stack) 예제
- 배열을 사용해서 스택 구현
- java.util.Stack 클래스 이용
- 배열을 사용해서 스택 구현
- index가 0부터 시작하므로 초기 상태를 top = -1로 설정
- top이 -1이면, empty, underflow
- push 하려면 --top
- pop은 top--
MyStack.java
package Stack;
public class MyStack {
// 멤버 변수
private int stackSize; // 스택 크기
private int top; // 스택 포인터
private char[] stackArr; // 스택(배열) : 배열 변수만 선언. 아직 할당되지 않음
// 생성자: 스택 초기화
// 배열 인덱스는 0부터 시작
// top 초기화는 -1로 설정
public MyStack(int stackSize) {
top = -1;
this.stackSize = stackSize; // 스택 크기 설정
stackArr = new char[this.stackSize]; // 스택 배열 생성
}
// 메서드
// 스택이 비었는지 확인하는 isEmpty()
// 결과 반환: true / false
public boolean isEmpty() {
return top == -1; // top이 -1이면 true, 아니면 false 반환
}
// 스택이 가득 차있는지 확인하는 isFull()
// 결과 반환: true / false
// 가득 찬 상태: top이 4인 경우, (즉, stackSize -1)
// stackSize: 5
// 스택 index: 0,1,2,3,4
public boolean isFull() {
return top == stackSize-1;
}
// 스택에 데이터 삽입하는 push()
// (1) 삽입 전에 Overflow 발생하는지 확인: isEmpty() 호출해서 결과 받아서 확인
// (2) Full이 아니면 top을 하나 증가한 위치에 데이터 삽입 ++top
// 삽입하기 위해 데이터 매개변수 받음
// 직접 스택에 삽입하고 종료 -> 반환값 없음
public void push(char item) {
if(isFull()) {
System.out.println("Stack Full. Overflow");
}
else{
// 초기값이 -1이므로, push 할 때 먼저 1 증가
stackArr[++top] = item;
}
}
// 스택에 데이터를 삭제하는 pop()
// Empty가 아니면 top 위치에 있는 데이터 삭제
// 삭제 후 top 1 감소시켜 :top--
//
public char pop() {
if(isEmpty()) {
System.out.println("Stack Empty. UnderFlow");
return 'E'; // 형식적인 return 값
}
else{
// top 위치에 있는 데이터 반환하고 top을 1 감소시킴
return stackArr[top--];
}
}
// 스택의 최상위 데이터를 출력하는 peek()
// (1) 먼저 스택이 비었는지 확인
// (2) 최상위 데이터 (top 위치에 있는 데이터) 반환
// 최상위 데이터(문자) 반환하므로 반환형 있음
public char peek() {
if(isEmpty()){
System.out.println("Stack Empty");
return 'E';
}
else{
// 현재 최상위 위치(top의 위치)의 값 반환
return stackArr[top];
}
}
// 스택의 내용을 비우는 clear()
public void clear() {
top = -1;
}
// 스택의 전체 데이터를 출력하는 showStack()
// 출력만 하고 반환값 얻음
// 먼저 출력하지 전에 스택이 비었는지 확인
// 스택에 있는 모든 요소의 값 출력 (배열의 모든 요소의 값 출력)
public void showStack() {
if(isEmpty()) {
System.out.println("Stack Empty");
}
else {
System.out.print("Stack items: ");
for(int i = 0; i <= top; i++){
System.out.print(i + ":" + stackArr[i] + " ");
}
System.out.println("\ntop : "+ top);
}
}
}
MyStackMain.java
package Stack;
public class MyStackMain {
public static void main(String[] args) {
// 스택 크기 설정
int stackSize = 5;
MyStack stk = new MyStack(stackSize);
System.out.print("Stack 초기 상태: ");
stk.showStack();
System.out.println("\npop 수행");
stk.pop();
System.out.println("\na, b, c push 수행");
stk.push('a');
stk.push('b');
stk.push('c');
stk.showStack();
System.out.println("\n최상위 값: " + stk.peek());
System.out.println("\nd, e push 수행");
stk.push('d');
stk.push('e');
stk.showStack();
System.out.println("\nf push 수행");
stk.push('f');
System.out.println("\npop 2번 수행");
System.out.println("pop한 값: "+stk.pop());
System.out.println("pop한 값: "+stk.pop());
stk.showStack();
System.out.println("\nclear 수행");
stk.clear();
stk.showStack();
}
}
[OUTPUT]
Stack 초기 상태: Stack Empty
pop 수행
Stack Empty. UnderFlow
a, b, c push 수행
Stack items: 0:a 1:b 2:c
top : 2
최상위 값: c
d, e push 수행
Stack items: 0:a 1:b 2:c 3:d 4:e
top : 4
f push 수행
Stack Full. Overflow
pop 2번 수행
pop한 값: e
pop한 값: d
Stack items: 0:a 1:b 2:c
top : 2
clear 수행
Stack Empty
StackTest.java (java.util.Stack 사용)
package Stack;
import java.util.Stack;
public class StackTest {
public static void main(String[] args) {
Stack<String> stk = new Stack<String>();
stk.push("홍길동");
stk.push("이몽룡");
stk.push("성춘향");
for(int i = 0; i < stk.size(); i++) {
System.out.println(i + ": " + stk.get(i));
}
System.out.println("스택 크키: "+ stk.size());
System.out.println("최상위 값: "+stk.peek());
System.out.println("이몽룡 들어 있는가? : "+stk.contains("이몽룡"));
System.out.println("pop 수행: "+stk.pop());
for(int i = 0; i<stk.size(); i++){
System.out.println(i + " : "+ stk.get(i));
}
System.out.println("clear 수행");
stk.clear();
System.out.println("empty? : "+ stk.empty());
}
}
[OUTPUT]
0: 홍길동
1: 이몽룡
2: 성춘향
스택 크키: 3
최상위 값: 성춘향
이몽룡 들어 있는가? : true
pop 수행: 성춘향
0 : 홍길동
1 : 이몽룡
clear 수행
empty? : true
'프로그래밍 언어 > 자료구조 & 알고리즘' 카테고리의 다른 글
자료구조 - 연결리스트(1) 연결 리스트 (0) | 2021.11.29 |
---|---|
자료구조 - 순차리스트(2) 큐(Queue), 데크(Deque) (0) | 2021.11.29 |
알고리즘 설계 기법 - 동적 프로그래밍 기법 (0) | 2021.11.29 |
알고리즘 설계 기법 - Greedy 알고리즘/욕심쟁이 기법 (0) | 2021.11.29 |
알고리즘의 설계 기법 - 분할정복기법/분할정복 알고리즘 (0) | 2021.11.26 |