1 / 63

자 료 구 조

자 료 구 조. 제 3 장 스택과 큐. 3.1 C++ 의 템플리트. 3.1 C++ 의 템플리트. ▶ 템플리트 함수 - 클래스와 함수의 재사용에 기여 (1) 템플리트 함수를 사용하지 않는 경우 ( 예 ) 정수 배열을 위한 선택 정렬 함수 sort( 프로그램 1.6) 부동 소수점 수의 배열을 정렬하려면 ? . 첫째 행에서 int *a 를 float *a 로 변경 . 둘째 행에서 정수를 부동 소수점 수로 변경 . 11 번째 행에서 int 를 float 로 변경

ashton-wong
Download Presentation

자 료 구 조

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 자 료 구 조 제 3 장 스택과 큐

  2. 3.1 C++의 템플리트

  3. 3.1 C++의 템플리트 • ▶ 템플리트 함수 • - 클래스와 함수의 재사용에 기여 • (1) 템플리트 함수를 사용하지 않는 경우 • (예) 정수 배열을 위한 선택 정렬 함수 • sort(프로그램 1.6) • 부동 소수점 수의 배열을 정렬하려면? • . 첫째 행에서 int *a를 float *a로 변경 • . 둘째 행에서 정수를 부동 소수점 수로 변경 • . 11번째 행에서 int를 float로 변경 • (2) 템플리트 / 인수화타입(parameterized type)을 • 이용한 해결 • - 다음 템플리트 함수 sort는 int나 float의 배열을 • 모두 정렬

  4. 3.1 C++의 템플리트 • ------------------------------------------ • template <class KeyType> • void sort(KeyType *a, int n){ • // n개의 KeyType a[0]부터 a[n-1]까지 비감소순으로 정렬 • for( int i=0; i<n; i++) • { • int j = i; • // a[i]와 a[n-1] 사이에 가장 작은 KeyType을 찾는다 • for( int k = i+1; k<n; k++) • if( a[k] < a[j]) j = k; • // 교환 • KeyType temp = a[i]; a[i] = a[j]; a[j] = temp; • } • } • ------------------------------------------ • 프로그램 3.1: 템플리트를 이용한 선택 정렬 • - 템플리트 함수 sort 이용 예 • ------------------------------------------ • float farray[100]; • int intarray[250]; • ... • // 이 시점에서 배열들이 초기화된다고 가정한다 • sort(farray, 100); • sort(intarray, 250); • ------------------------------------------ • 프로그램 3.2: 템플리트 인스턴스화를 보여주는 코드의 일부

  5. 3.1 C++의 템플리트 • * 사용상의 주의 사항 : • . <, =, 및 복사 생성자 • . int와 float에 대해서는 자동적으로 정의 • . 사용자 정의 데이타 타입에 대해서는 별도로 정의 • 하여야 함 • (예) sort를 이용해 Rectangle 배열을 넓이 • 오름차순으로 정렬 • -> operator < 정의 필요 • -> 지정 연산자, 복사 생성자는 컴파일러의 묵시적 • 구현으로 충분

  6. 3.1 C++의 템플리트 • ▶ 템플리트 클래스 • - 클래스의 재사용에 기여 • (1) 컨테이너 클래스(container class) • - 여러 데이타 객체들을 저장하는 데이타 구조를 • 표현하는 클래스 • (예) 배열, 백(Bag) • - 객체들의 삽입과 삭제가 가능 • - 백(Bag) • . 동일한 원소가 여러 번 나타남 • . 원소 위치, 삭제 연산시 어떤 원소가 제거 • 되는지는 문제 안됨 • -> 삽입: 해당 원소를 배열의 첫번째 가용 • 위치에 저장 • -> 삭제: 배열 중앙 위치 원소 삭제. 그 오른쪽 • 모든 원소는 한 자리씩 왼쪽으로 이동.

  7. 3.1 C++의 템플리트 • (2) 템플리트 클래스를 사용하지 않은 Bag 클래스 정의 예 • ----------------------------------------- • class Bag { • public: • Bag (int MaxSize = DefaultSize); //생성자 • ~Bag(); // 파괴자 • void Add(int); // 정수 하나를 백에 삽입 • int *Delete(int&); //백에서 정수 하나를 삭제 • Boolean IsFull(); • // 백이 포화상태이면 TRUE, 그렇지 않으면 FALSE를 반환 • Boolean IsEmpty(); • // 백이 공백상태이면 TRUE, 그렇지 않으면 FALSE를 반환 • private: • void Full(); // 백이 포화상태일 때의 조치 • void Empty(); // 백이 공백상태일 때의 조치 • int *array; • int MaxSize; // 배열의 크기 • int top; // 배열에서 원소가 들어 있는 가장 높은 위치 • -----------------------------------------프로그램 3.3: 정수를 포함하는 클래스 Bag의 정의

  8. - 클래스 Bag의 연산 구현 • --------------------------------------- • Bag::Bag (int MaxBagSize): MaxSize (MaxBagSize) • { array = new int[MaxSize]; top = -1; } • Bag::~Bag() { delete [] array; } • inline Boolean Bag::IsFull() • { if (top == MaxSize-1) return TRUE; • else return FALSE; } • inline Boolean Bag::IsEmpty() • { if (top == -1) return TRUE; • else return FALSE; } • inline void Bag::Full() • { cerr << "Data structure is full" << endl; } • inline void Bag::Empty() • { cerr << "Data structure is empty" << endl; } • void Bag::Add(int x) • { if( IsFull()) Full(); • else array[++top] = x; } • int* Bag::Delete(int& x) • { if( IsEmpty()) { Empty(); return 0; } • int deletePos = top/2; x = array[deletePos]; • for ( int index = deletePos; index<top; index++) • array[index] = array[index+1]; • //배열의 상반을 집약한다 • top--; return &x; • } • --------------------------------------- • 프로그램 3.4: Bag에 대한 연산들의 구현

  9. 3.1 C++의 템플리트 • (3) 템프리트 클래스를 이용한 Bag의 구현 • - 어떠한 데이타 타입의 객체들도 저장 • -----------------------------------------template <class Type> • class Bag • { • public: • Bag (int MaxSize = DefaultSize); //생성자 • ~Bag(); // 파괴자 • void Add(const Type&); // 원소 하나를 백에 삽입 • Type *Delete(Type&); //백에서 원소 하나를 삭제 • Boolean IsFull(); • // 백이 포화상태이면 TRUE, 그렇지 않으면 FALSE를 반환 • Boolean IsEmpty(); • // 백이 공백상태이면 TRUE, 그렇지 않으면 FALSE를 반환 • private: • void Full(); // 백이 포화상태일 때의 조치 • void Empty(); // 백이 공백상태일 때의 조치 • Type *array; • int MaxSize; // 배열의 크기 • int top; // 배열에서 원소가 들어 있는 가장 높은 위치 • } • ----------------------------------------- • 프로그램 3.5: 템플리트 클래스 Bag의 정의 • - 템플리트 클래스 Bag을 int와 Rectangle로 인스턴스화 • Bag<int> a; Bag<Rectangle> r;

  10. -------------------------------------- • template <class Type> • Bag<Type>::Bag (int MaxBagSize): • MaxSize (MaxBagSize) { • array = new Type[MaxSize]; • top = -1; • } • template <class Type> • Bag<Type>::~Bag() { delete [] array; } • template <class Type> • void Bag<Type>::Add(const Type& x) { • if( IsFull()) Full(); • else array[++top] = x; • } • template <class Type> • Type* Bag<Type>::Delete(Type& x) { • if( IsEmpty()) { Empty(); return 0;} • int deletePos = top/2; • x = array[deletePos]; • for ( int index = deletePos; index<top; index++) • array[index] = array[index+1]; //배열의 상반을 • //집약한다 • top--; • return &x; • } • -------------------------------------- • 프로그램 3.6: Bag에 대한 연산들의 구현

  11. 3.2 스택 추상 데이타 타입

  12. 3.2 스택 추상 데이타 타입 • - 순서 리스트의 특별한 경우 • 순서 리스트 : A = a0, a1, ... , an-1, n ≥ 0 • ▶ 스택(stack) • 톱(top)이라고 하는 한쪽 끝에서 모든 삽입(push)과 삭제(pop)가 일어나는 순서 리스트 . 스택 S=(a0,....,an-1) : a0는 bottom, an-1은 top의 원소 . ai는 원소 ai-1(0<i<n)의 위에 있음 - 후입선출(LIFO, Last-In-First-Out) 리스트 - 원소 A,B,C,D,E를 삽입하고 한 원소를 삭제하는 예

  13. 3.2 스택 추상 데이타 타입 • 그림 3.1: 스택에서의 삽입과 삭제

  14. 3.2 스택 추상 데이타 타입 • 예제 3.1 [시스템 스택]: • - 프로그램 실행시 함수 호출을 처리 - 함수 호출시 활성 레코드 (activation record) 또는 스택 프레임(stack frame) 구조 생성 . 이전의 스택 프레임에 대한 포인터 . 복귀 주소 . 지역 변수 . 매개 변수 - 함수가 자기자신을 호출하는 순환 호출도 마찬가지 로 처리 -> 순환 호출시마다 새로운 스택 프레임 생성 -> 최악의 경우 가용 메모리 전부 소모

  15. 3.2 스택 추상 데이타 타입 • - 주 함수가 함수 a1을 호출하는 예 그림 3.2: 함수 호출 후의 시스템 스택

  16. - 스택 ADT • --------------------------------------- • template <class KeyType> • class Stack{ • // objects: 0개 이상의 원소를 가진 유한 순서 리스트 • public: • Stack (int MaxStackSize = DefaultSize); • // 최대 크기가 MaxStackSize인 공백 스택을 생성 • Boolean IsFull(); • // 스택 내에 있는 원소의 수가 스택의 최대크기와 같은 • // 경우 TRUE (1), 그렇지 않은 경우 FALSE (0)을 반환 • void Add(const KeyType& item); • // IsFull()이 TRUE이면 StackFull()을 호출하고, • // 그렇지 않으면 스택의 톱에 item을 삽입 • Boolean IsEmpty(); • // 스택 내에 있는 원소의 수가 0인 경우 TRUE (1), • // 그렇지 않은 경우 FALSE (0)을 반환 • KeyType* Delete(KeyType&); • // IsEmpty()가 TRUE이면 StackEmpty()을 호출하고 • // 0을 반환, • // FALSE 이면 스택의 톱 원소를 제거하고 그 포인터를 • 반환 • }; • ----------------------------------------- • ADT 3.1: 추상 데이타 타입 Stack

  17. 3.2 스택 추상 데이타 타입 - 스택 구현: 일차원 배열 stack[MaxSize] 사용 . i번째 원소는 stack[i-1]에 저장 . 변수 top은 스택의 최상위 원소를 가리킴 (초기 : top = -1) ---------------------------------------- Private: int top; KeyType *stack; int MaxSize; Template <class KeyType> Stack<KeyType>::Stack (int MaxStackSize): MaxSize (MaxStackSize) { stack = new KeyType[MaxSize]; top = -1; }

  18. 3.2 스택 추상 데이타 타입 - 멤버 함수 IsFull()과 IsEmpty() 구현 template <class KeyType> inline Boolean Stack<KeyType>::IsFull() { if (top == MaxSize-1) return TRUE; else return FALSE; } template <class KeyType> inline Boolean Stack<KeyType>::IsEmpty() { if (top == -1) return TRUE; else return FALSE; }

  19. 3.2 스택 추상 데이타 타입 - Add와 Delete 연산 구현 --------------------------------- template <class KeyType> void Stack<KeyType>::Add(const KeyType& x) // stack에 x를 삽입 { if (IsFull()) StackFull(); else stack[++top] = x; } ----------------------------------------프로그램 3.7: 스택에로의 삽입 ----------------------------------------template <class KeyType> KeyType* Stack<KeyType>::Delete(KeyType& x) // stack에서 톱 원소를 제거 { if (IsEmpty()) { StackEmpty(); return 0; } x = stack[top--]; return &x; } ----------------------------------------프로그램 3.8: 스택으로부터 삭제 *주의 : Delete의 반환값은 KeyType* 타입 -> 공백인 경우는 0을 반환

  20. 3.3 큐 추상 데이터 타입

  21. 3.3 큐 추상 데이터 타입 ▶ 큐(queue) - 한쪽 끝(rear)에서 삽입이 일어나고 반대쪽 끝(front)에서 삭제가 일어나는 순서 리스트 . 큐 Q=(a0, a1, ... , an-1): a0는 앞(front) 원소 an-1은 뒤(rear) 원소 . ai는 ai-1(1≤i<n)의 뒤에 있다고 함 - 선입선출(FIFO, First-In-First-Out) 리스트

  22. 3.3 큐 추상 데이터 타입 - 원소 A,B,C,D,E를 삽입하고 한 원소를 삭제하는 예 그림 3.4: 큐에서의 삽입과 삭제

  23. 3.3 큐 추상 데이터 타입 - 큐 ADT ------------------------------------------ template <class KeyType> class Queue{ // objects: 0개 이상의 원소를 가진 유한 순서 리스트 public: Queue (int MaxQueueSize = DefaultSize); // 최대 크기가 MaxQueueSize인 공백 큐를 생성 Boolean IsFull(); // 큐 내에 있는 원소의 수가 큐의 최대크기와 같은경우 // TRUE (1), 그렇지 않은 경우 FALSE (0)을 반환 void Add(const KeyType& item); // IsFull()이 TRUE이면 QueueFull()을 호출, // 그렇지 않으면 큐의 뒤에 item을 삽입 Boolean IsEmpty(); // 큐 내에 있는 원소의 수가 0인 경우 TRUE (1), // 그렇지 않은 경우 FALSE (0)을 반환 KeyType* Delete(KeyType&); // IsEmpty()가 TRUE이면 QueueEmpty()를 호출하고 // 0을 반환, FALSE이면 큐의 앞 원소를 제거하고 // 그 포인터를 반환 }; ------------------------------------------ ADT 3.2: 추상 데이타 타입 Queue

  24. 3.3 큐 추상 데이터 타입 • - 큐의 구현: 1차원 배열 이용 • . 변수 front는 큐에서 첫 원소의 위치 • 보다 하나 작은 위치 • . 변수 rear는 큐에서 마지막 원소의 위치 • Private: • int front, rear; • KeyType *queue; • int MaxSize; • template <class KeyType> • Queue<KeyType>::Queue (int MaxQueueSize): • MaxSize (MaxQueueSize) • { • queue = new KeyType[MaxSize]; • front = rear = -1; • }

  25. 3.3 큐 추상 데이터 타입 - 멤버 함수 IsFull()과 IsEmpty() 구현 template <class KeyType> inline Boolean Queue<KeyType>::IsFull() { if (rear == MaxSize-1) return TRUE; else return FALSE; } template <class KeyType> inline Boolean Queue<KeyType>::IsEmpty() { if (front == rear) return TRUE; else return FALSE; } * 주의 : IsFull() 구현은 ADT 3.2 명세와 다름 - rear = MaxSize-1이고 front > -1이 될 수 있기 때문 -> 이 경우 큐 원소수가 MaxSize보다 작음

  26. 3.3 큐 추상 데이터 타입 - Add와 Delete 구현 -------------------------------------- template <class KeyType> void Queue<KeyType>::Add(const KeyType& x) // queue에 x를 삽입 { if (IsFull()) QueueFull(); else queue[++rear] = x; } -------------------------------------- 프로그램 3.9: 큐에 삽입 -------------------------------------- template <class KeyType> KeyType* Queue<KeyType>::Delete(KeyType& x) // 큐에서 앞 원소를 제거 { if (IsEmpty()) { QueueEmpty(); return 0;} x = queue[++front]; return &x; } --------------------------------------- 프로그램 3.10: 큐에서의 삭제

  27. 3.3 큐 추상 데이터 타입 • ▶ 큐의 순차적 표현의 문제점 예 • 예제 3.2 [작업 스케쥴링]: • - 운영체제의 작업 큐(job queue) : FCFS 스케쥴링 • 작업들이 큐에 들어가고 나옴에 따라 큐는 점차 • 오른쪽으로 이동 • -> 결국 rear 값이 MaxSize-1과 같아져서 큐가 • 포화 상태가 됨 • - QueueFull()의 업무 • . 전체 큐를 왼쪽으로 이동(shift) • -> 첫째 원소가 q[0]에 가도록 • . front를 -1로, rear 값도 조정 • . 이러한 배열 이동에 많은 시간 소요 • -> 최악의 경우: O(MaxSize)

  28. 3.3 큐 추상 데이터 타입 • 그림 3.5: 큐에서의 삽입과 삭제 • 큐 포화시마다 전체 큐를 왼쪽 이동시 • 최악의 경우 • . 큐에 n개의 원소 J1,...,Jn이 있음 • . 그 후 삽입과 삭제가 교대로 이루어짐 • . 새 원소 삽입시마다 n-1개의 원소 가진 큐 • 전체 왼쪽 이동

  29. 3.3 큐 추상 데이터 타입 그림 3.6: 큐의 예

  30. 3.3 큐 추상 데이터 타입 ▶ 순차적 큐의 문제 해결: 원형 큐 - 배열 queue[MaxSize]를 원형으로 취급 -> rear == MaxSize-1이면 q[0]가 빈 경우 q[0]에 삽입 - 최대 원소 수: MaxSize가 아니라 MaxSize-1 -> front == rear가 포화상태인지, 공백상태인지 구분하기 위함 - 초기: front == rear == 1 - 공백: front == rear

  31. 3.3 큐 추상 데이터 타입 - 네 원소 J1-J4 가진 원형 큐 그림 3.7: MaxSize = n 이고 네 개의 작업 J1, J2, J3, J4를 가진 원형 큐

  32. 3.3 큐 추상 데이터 타입 - 원형 큐에 대한 삽입 연산 . rear 증가(circular shift) if (rear == MaxSize-1) k = 0; else k = rear+1; ≡ (rear+1) % MaxSize . 포화 상태 검사(front == k), 포화 아니면 새원소 삽입 ------------------------------------ template <class KeyType> void Queue<KeyType>::Add(const KeyType& x) // 원형 큐에 x를 삽입 { int k = (rear+1) % MaxSize; if (front == k) QueueFull(); else queue[rear=k] = x; } ------------------------------------ 프로그램 3.11: 원형 큐에 삽입

  33. 3.3 큐 추상 데이터 타입 - 원형 큐에 대한 삭제 연산 . 먼저 empty 테스트 . front 이동: ++front %= MaxSize ------------------------------------ template <class KeyType> KeyType* Queue<KeyType>::Delete(KeyType& x) // 원형 큐에서 앞 원소를 제거 { if (front == rear) { QueueEmpty(); return 0; } x = queue[++front %= MaxSize]; return &x; } ------------------------------------ 프로그램 3.12: 원형 큐에서의 삭제

  34. 3.4 C++의 서브타입과 계승

  35. 3.4 C++의 서브타입과 계승 - 계승(inheritance) : 추상 데이타 타입간의 서브타입(subtype) 관계를 표현 . IS-A(~의 하나이다) 관계 ex) . 의자: 가구의 서브타입(IS-A) . 사자: 포유류의 서브타입(IS-A) . 직사각형: 다각형의 서브타입(IS-A). - Bag과 Stack간의 관계 . 백(bag) : 단순히 원소들이 삽입과 삭제가 될 수 있는 자료구조 . 스택 : 원소들이 후입선출 순서에 따라 삭제되는 자료 구조(제한적) . Stack은 Bag의 하나(IS-A) 즉 Stack은 Bag의 서브타입

  36. 3.4 C++의 서브타입과 계승 - C++의 공용 계승(public inheritance) : IS-A 관계를 표현 class Stack : public Bag { } - 일반적인 추상 데이타 타입을 표현하는 클래스 : 기본 클래스(base class) - Bag - 추상 데이타 타입을 표현하는 클래스 : 파생 클래스(derived class) - Stack Note : Virtual 멤버 함수 선언 : 기본 클래스 구현 : 파생 클래스

  37. 3.4 C++의 서브타입과 계승 -----------------------------------------class Bag { Public: Bag (int MaxSize = DefaultSize); // 생성자 virtual ~Bag(); // 파괴자 virtual void Add(int); // 백에 원소를 삽입한다 virtual int *Delete(int&); // 백에서 원소를 삭제한다 virtual Boolean IsFull(); // 백이 포화상태이면 TRUE, // 그렇지 않으면 FALSE를 반환 virtual Boolean IsEmpty(); // 백이 공백상태이면 TRUE, // 그렇지 않으면 FALSE를 반환 Protected: virtual void Full(); // 백이 포화상태일 때의 조치 virtual void Empty();// 백이 공백상태일 때의 조치 int *array; int MaxSize; // 배열의 크기 int top; // 배열에서 원소가 있는 가장 높은 위치 }; class Stack: public Bag { Stack (int MaxSize = DefaultSize); // 생성자 ~Stack(); // 파괴자 int *Delete(int&); // 스택에서 원소를 삭제한다 }; -----------------------------------------프로그램 3.13: Bag과 Stack의 정의

  38. 3.4 C++의 서브타입과 계승 • 계승의 의미: • - 파생 클래스(Stack)가 기본 클래스(Bag)의 모든 • 비전용(공용, 보호) 멤버(데이타와 함수)들을 • 계승받음 • 계승된 멤버들은 기본 클래스에서 가졌던 것과 • 똑같은 접근 레벨을 파생클래스에서도 가짐 • - 계승 받은 멤버함수는 같은 프로토 타입 유지 • : 기본 클래스 인터페이스 재사용

  39. 3.4 C++의 서브타입과 계승 ---------------------------------------- Stack::Stack (int MaxStackSize): Bag(MaxStackSize) { } // Stack 생성자는 Bag 생성자를 호출한다. Stack::~Stack() { } // Stack이 파괴될 때 Bag 파괴자는 자동으로 호출된다. // 이것이 array가 제거되는 것을 보장한다. int *Stack::Delete(int& x) { if (IsEmpty()) Empty(); return 0; x = array[top--]; return &x; } ---------------------------------------- 프로그램 3.14: Stack 연산의 구현

  40. 계승 작동 예 : Bag b(3); //크기3의 배열을 생성하기위하여 Bag의 생성자를 이용 Stack s(3); //크기3의 배열을 생성하기위하여 Stack의 생성자를 이용 b.Add(1); b.Add(2); b.Add(3); // Bag::Add를 사용한다. // Bag::Add는 함수 Bag::IsFull과 Bag::Full을 호출 s.Add(1); s.Add(2); s.Add(3); // Stack::Add가 정의되지 않았으므로 Bag::Add를 사용 // Bag::Add는 Bag::IsFull과 Bag::Full을 호출 // 왜냐하면 이들은 Stack에서 재정의되지 않았기 때문 int x; b.Delete(x); // Bag::Delete를 사용 // 이것은 Bag::IsEmpty와 Bag::Empty를 호출 s.Delete(x); // Stack::Delete를 사용 // 이것은 Bag::IsEmpty와 Bag::Empty를 호출 // 왜냐하면, 이들이 Stack에서 재정의되지 않았기 때문

  41. 3.4 C++의 서브타입과 계승 - Queue ADT도 Bag의 서브타입 . 선입선출 순서로 원소가 삭제되는 자료 구조 . Queue도 Bag의 한 파생 클래스로 표현 가능

  42. 3.5 미로 문제

  43. 0 1 0 1 1 0 0 0 0 1 0 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 0 1 0 0 1 1 1 1 0 0 0 1 0 1 1 1 1 1 0 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0 1 1 1 1 0 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 0 0 1 0 1 1 0 1 0 0 0 1 0 1 1 1 1 1 0 1 1 1 0 0 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 0 1 1 0 0 1 1 0 1 0 1 0 0 1 1 1 1 0 1 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 0 1 1 1 1 0 0 0 1 1 3.5 미로 문제 미로는 1≤i≤m이고 1≤j≤p인 이차원 배열 maze[m][p]로 표현 1 : 통로가 막혀 있음 0 : 통과할 수 있음 입구 출구 그림 3.8: 예제 미로 maze[m+2][p+2] mark[m+2][p+2] : 시도한 위치 표시

  44. 3.5 미로 문제 현재의 위치 x : maze[i][j] 그림 3.9 : 가능한 이동

  45. 3.5 미로 문제 struct offsets { int a, b; }; enum directions {N, NE, E, SE, S, SW, W, NW}; offsets move[8]; 그림 3.10 : 이동 테이블 [i][j]에서 SW, 즉 [g][h]로 이동 → g = i + move[sw].a; h = j + move[sw].b;

  46. 3.5 미로 문제 stack은 미로 입구 좌표, 방향(dir)은 동(E)으로 초기화 while (stack이 공백이 아님) { (i, j, dir) = stack의 top에 있는 좌표와 방향; while (이동이 계속 가능) { (g, h) = 다음 이동 좌표; if ((g == m) && (h == p)) 경로 발견 성공; if (!maze[g][h] // 적법한 이동 && !mark[g][h]) // 전에 온 적이 없는 곳 { mark[g][h] = 1; dir = 다음에 시도할 방향; (i, j, dir)를 stack의 top에 삽입; i =g; j = h; dir = north; } } } cout << "No path found" << endl; -------------------------------------- 프로그램 3.15: 초기 미로 알고리즘

  47. 3.5 미로 문제 입구 출구

  48. 3.5 미로 문제 - path에서 배열 maze, mark, move는 전역적이라고 가정 - stack은 items의 스택으로 정의 struct items { int x, y, dir; };

  49. ------------------------------------------ void path(int m, int p) { // 경로가 있으면 출력한다. maze[0][i]= maze[m+1][i] = // maze[j][0] = maze[j][p+1] = 1, 0≤i≤p+1, 0≤j≤m+1. // (1, 1)에서 시작 mark[1][1]=1; stack<items> stack(m*p); items temp; temp.x = 1; temp.y = 1; temp.dir = E; stack.Add(temp); while (!stack.IsEmpty()) { // 스택이 공백이 아님 temp = *stack.Delete(temp); // 스택에서 삭제 while (d < 8) { // 앞으로 이동 int g = i + move[d].a; int h = j + move[d].b; if ((g == m) && (h == p)) { // 출구 도착,경로 출력 cout << stack; cout << i << " " << j << endl; // 경로상의 마지막 두 위치 cout << m << " " << p << endl; return; } if ((!maze[g][h]) && (!mark[g][h])) {//새로운 위치 mark[g][h] = 1; temp.x = i; temp.y = j; temp.dir = d+1; stack.Add(temp); // 스택에 삽입 i = g; j = h; d = N; // (g, h)로 이동 } else d++; // 다음 방향으로 시도 } } cout << "no path in maze" << endl; } ------------------------------------------ 프로그램 3.16: 미로 탐색 함수

  50. 3.5 미로 문제 - operator << ; stack 과 item에 대해 다중화 - friend로 선언되어 stack의 전용 데이타 멤버 접근 가능 -----------------------------------------template <class KeyType> ostream& operator<<(ostream& os, Stack<KeyType>& s) { os << "top = " << s.top << endl; for (int i = 0; i <= s.top; i++) os << i << ":" << s.stack[i] << endl; return os; } ostream& operator<<(ostream& os, items& item) { return os << item.x << "," << item.y << "," << item.dir; } ----------------------------------------- 프로그램 3.17: 연산자 <<의 다중화

More Related