ed6f8819857b110a382560fa4b9acbdc.ppt
- Количество слайдов: 164
제 1장 기본 개념Ⅰ
컴퓨터 기억장치 자료 보조기억장치 정보 프로그램, 데이터 자료구조→자료저장, 이용 알고리즘→프로그램
자료구조의 영역 광의 자료구조 협의 자료구조 기본 자료 선형: 레코드, 배열, 스택, 큐 연결리스트 비선형: 트리, 그래프 화일구조 데이터베이스 구조
교재의 구성 기본개념 선형구조: 배열 스택, 큐 연결리스트 비선형구조: 트리 그래프 자료구조응용: 탐색, 정렬
선형 구조 배열 : 스택 : 큐 : 연결리스트:
비선형 구조 트리 1: N 그래프 N: M
알고리즘의 특성 입력: 외부 제공 자료가 있을수 있음 출력: 한가지 이상의 결과 생성 명확성: 각 명령은 명확 유한성: 한정된 단계 실행 후 종료 유효성: 컴퓨터 처리 가능
알고리즘 기술 방법 알고리즘 기술언어 사용 자연어에 의한 표현 한글 또는 영문 슈도코드(PSEUDO CODE) 도형에 의한 표현 흐름도(FLOW CHART) 박스(BOX) 다이어그램
자료 추상화 자료형(data type)은 객체(object)와 그 위에 작동하는 연 산(operation)의 집합이다. 예 - int {0, +1, +2, -1, -2, . . . INT_MAX, . . } - char {문자 1자리} 추상 자료형(ADT)은 객체의 명세와 그 연산의 명세가 그 객체의 표현과 연산의 구현으로부터 분리된 자료형이다.
자연수의 추상자료형 structure Natural_Number object : 0부터 INT_MAX까지 Function : x, y, TRUE, FALSE, +, -, <, == Nat_No Zero( ) : : = 0 Boolean Is_Zero(x) : : =if (x) return FALSE else return TRUE Nat_No Add(x, y) : : = if((x+y)<=INT_MAX) return x+y else return INT_MAX Boolean Equal(x, y) : : =if (x==y) return TRUE else return FALSE Nat_No Successor(x) : : = if((x=INT_MAX) return x else return x+1 Nat_No Subtract(x, y) : : = IF (x<y) return 0 else return x-y END
SPARKS의 구성 선언문 지정문 조건문(if, case) 반복문(for, while, repeat, loop~forever) procedure문 입출력문
선언문 변수선언 : 자료형 지정 지정문 LINK(P)←r a←a+1 P←X; q← 0 procedure문 procedure NAME(parameter list) call NAME(parameter list) return(expr)
프로시저간의 자료전달 call by value call by reference call by name 입출력문 read (argument list) print (argument list)
순환(recursion) ®직접순환: A→A’ ®간접순환: A→B→A
procedure PERM(A, k, n) if k=n then [print(A): return] B←A for i←k to n do call INTERCHANGE(A, k, i) call PERM(A, k+1, n) A←B end PERM
proc PERM(A, 1, 3) if k=n for i←k to n do call PERM(A, k+1, n) end PERM A = {a, b, c} k=1 n=3 proc PERM(A, 2, 3) if k=n proc PERM(A, 3, 3) if k=n [print(A): return] for i←k to n do call INCHANGE(A, k, i) call PERM(A, k+1, n) end end PERM
성능분석 공간복잡도 고정공간+가변공간 S(P)=C+SP(I) 시간복잡도 빈도수계산 TP(n)=Ca. ADD(n)+Cs. SUB(n)··
procedure SUM(A, n) tsum← 0 for i← 1 to n do tsum ←tsum+A(i) end print(tsum) end SUM
연산시간 표기법 모든 n, n≥ no에 대해 f(n)≤cg(n)을 만족하는 양의 상수 C와 no가 존재하기만 하면 f(n)=O(g(n))이다. f(n)≥cg(n)이면, f(n)=Ω(g(n)) c 1 g(n)≤f(n)≤c 2 g(n)이면, f(n)=θ(g(n))
O-notation f(n)=3 n+2 O(n) 2 2 f(n)=10 n +4 n+5 O(n ) f(n)=6*2 n+n 2 3 f(x)=5 x +600 X O(2 n) 3 O(x ) f(x)=100 X-1000 O(x)
연산시간함수의 변화 65536 32768 16384 8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 n 3 2 n n 2 nlog 2 n n log 2 n 1 2 4 8 16 32 64 128
연산시간 표현 O (1) : 상수 O(log 2 n) : 로그형 O (n) : 선형 O(n 2) : 평방형 O(n 3) : 입방형 O(2 n) : 지수형 O(1)<O(log 2 n)<O(n 2)<O(n 3)<O(2 n)
제 2장 배열
배열(array) <인덱스, 원소> 쌍의 집합. 각 쌍은 어느 한 인덱스가 주어질 때, 그와 연관된 원소 값이 결정되는 대응관계. 배열 이름이 a라면, a[인덱스]=원소 값
Structure Array objects : <index, value>쌍의 집합. functions: 모든 A ∈ Array, i ∈ index, x ∈ item, j, size ∈ integer ① Create(j, list) : : = return j차원의 배열. ② Retrieve(A, i) : : = if (i ∈ index) return 배열 A의 인덱스 i값과 관련된 항목. else return 에러. ③ Store(A, i, x) : : = if (i ∈ index) return 새로운 쌍<i, x>가 삽입된 배열 A. else return 에러. end Array
1차원 배열 A[n] A(0) A(2) . . . A(n-1) A[l: u] A(l) A(l+1) . . . A(u) * A[l: u] 배열원소: A[ㅣ], A[ㅣ+1], . . . , A[i], . . . , A[u] 주 소 : α α+1 α+[i-ㅣ] α+[u-ㅣ] 원소의 크기가 L일때: α+[i-ㅣ]·L
배열의 행우선과 열우선 다차원 배열을 1차원 메모리 표현, (행우선 순서, 열우선 순서) 2차원 배열 B[m][n]일 경우, 처음원소 : B(0, 0) 주소가 α일 때, 임의의 원소 B(i, j)의 주소는 - 행우선 : α + i*n +j - 열우선 : α + j*m +i
행우선과 열우선 A[3][2] 열 0 1 0 행 1 2 (0, 0) 0행 (0, 1) (1, 0) 1행 (0, 0) (1, 0) 0열 (2, 0) (1, 1) (0, 1) (2, 0) 2행 (2, 1) (1, 1) 1열 (2, 1) 행우선 열우선
행우선과 열우선 주소계산 공식 행우선 A(l 1: u 1, l 2: u 2), A(l 1, l 2)=α A(l 1, l 2+1)=α+1 A(i, j)=α+[(i-l 1)·u 2 +(j-l 2)]·L 열우선 A(l 1: u 1, l 2: u 2), A(l 1, l 2)=α A(l 1+1, l 2)=α+1 A(i, j)=α+[(j-l 2)·u 1 +(i-l 1)]·L
메모리 주소 Int list[5]; // 5개의 정수 값을 갖는 배열 선언// *plist[5]; //정수를 가리키는 5개의 포인터형 배열// 변수 메모리 주소 -----------list[0] 기본주소 = α list[1] α + sizeof(int) list[2] α + 2·sizeof(int) list[3] α + 3·sizeof(int) list[4] α + 4·sizeof(int)
순서리스트 i S = (a 1, a 2, …, an) i 리스트 길이(n) : 유한 i 리스트 읽음(left→right, right→left) : access i i번째 원소검색(1≤i≤n) : retrieve i i번째에 새로운 값 저장(1≤i≤n) : update i i번째에 새로운 원소삽입 : insert i→i+1 i i번째 원소 삭제 : delete i+1→i
Structure Polynomial objects : P(x) = a 1 xe 1 + ··· + anxen ; <ei, ai>의 순서쌍 집합. function: 모든 poly, poly 1, poly 2 ∈polynomial, coef ∈Coefficients, expon ∈Exponents ① Zero() : : = return 다항식, p(x) = 0 ② Is. Zero(poly) : : = if(poly) return FALSE else return TRUE ③ Coef(poly, expon) : : = if(expon ∈ poly) return 계수 else return 0 ④ Lead_Exp(poly) : : = return poly에서 제일 큰 지수
⑤ Attach(poly, coef, expon) : : = if(expon ∈ poly) return 에러 else return <coef, exp>항이 삽입된 다항식 poly ⑥ Remove(poly, expon) : : = if(expon ∈ poly) return 지수가 expon인 항이 삭제된 다항식 poly else return 에러 ⑦ Single. Mult(poly, coef, expon) : : =return 다항식 poly·coef·xexpon ⑧ Add(poly 1, poly 2) : : = return 다항식 poly 1 + poly 2 ⑨ Mult(poly 1, poly 2) : : = return 다항식 poly 1·poly 2 end polynomial
다항식의 배열표현 <표현1> 계수를 순서적으로 표현 A(x)=anxn + an-1 xn-1 + … a 1 x + a 0 A=(n, an-1, … , a 1, a 0) 길이: n+2 <표현2> 0이 아닌 계수만을 취한 표현 A'(x)=bm-1 xem-1 +bm-2 xem-2 +…, +b 0 e 0 A'=(m, em-1, bm-1, em-2, bm-2, …, e 0, b 0) 길이: 2 m+1
10 예)A=5 X +2 일 경우 <표현1> A=(n, an-1, … , a 1, a 0) 10 5 0 0 0 0 0 2 <표현2> A’=(m, em-1, bm-1, em-2, bm-2, …, e 0, b 0) 2 10 5 0 2
다항식 덧셈 알고리즘 * 표현 2의 응용 예 A(x) = 2 x 1000 +1 B(x) = x 4 +10 x 3 +3 x 2 +1
다항식 덧셈 알고리즘 while (starta <= finisha && startb <= finishb) switch (COMPARE(terms[starta]. expon, terms[startb]. expon)) { case -1: attach(terms[startb]. coef, terms[startb]. expon); startb++; break; case 0: coefficient = terms[starta]. coef + terms[startb]. coef; if (coefficient) attach(coefficient, terms[starta]. expon); starta++; startb++; break; case 1: attach(terms[starta]. coef, terms[starta]. expon); starta++; }
다항식 덧셈 알고리즘 void padd(int starta, int finisha, int startb, int finishb, int *startd, int *finishd); float coefficient; *startd = avail; for(; starta <= finisha; starta++) attach(terms[starta]. coef, terms[starta]. expon); for(; startb <= finishb; startb++) attach(terms[startb]. coef, terms[startb]. expon); *finishd = avial-1;
희소행렬.
행 a[0] 6 열 6 값 8 [1] 0 0 15 [1] [2] 0 3 22 [3] 0 5 [4] 1 [5] [6] [7] [8] 1 2 4 5 행 b[0] 6 열 6 값 8 0 0 15 [2] 0 4 91 -15 [3] 1 1 11 [4] 2 1 3 2 3 0 2 3 -6 91 28 [5] [6] [7] [8] 2 3 3 5 5 0 28 22 -6 -15 3원소 쌍으로 저장된 희소 행렬과 전치 행렬
void transpose(term a[], term b[]) B 1 2 0 0 0 8 5 1 0 4 2 15 91 0 -15 …… … { int n, i, j, currentb; n = a[0]. value; A 0 1 2 b[0]. row = a[0]. col; 1 0 0 15 ① b[0]. col = a[0]. row; 2 0 3 22 ② b[0]. value = n; 7 4 0 91 if (n > 0) { 8 5 2 28 currentb = 1; for (i =0; i = a[0]. col; i++) for (j = 1; j <= n; j++) if (a[j]. col ==i { b[currentb]. row = a[j]. col; b[currentb]. col = a[j]. row; b[currentb]. value = a[j]. value; currentb++; } } }
문자열 #define MAX_SIZE 100 /* 문자열의 최대 크기 */ char s[MAX_SIZE]="dog"; char t[MAX_SIZE]="house"; char s[]="dog"; char t[]="house"; s[0] s[1] s[2] s[3] d o g t[0] t[1] t[2] t[3] t[4] t[5] h o u s e
문자열 연산 #include <string. h> #define MAX_SIZE 100 /* 가장 긴 문자열의 길이 */ char string 1[MAX_SIZE], *s = string 1; char string 2[MAX_SIZE], *t = string 2; s a m o b t t o u i l temp 초기상태 Strncpy(temp, s, i) temp a temp a u t o temp u t o m a e Strcdt(temp, t) o b i l Strcdt(temp, s+i) e
제 3장 스택 & 큐
스택의 정의 STACK(1: n) (1차원 배열 형태) 한쪽 끝에서 삽입·삭제 LIFO(Last In First Out) 후입 선출 알고리즘 PUSH, POP 연산 H G F E D C B A
A B A ②A의 삽입 ③B의 삽입 top→ ①초기상태 top→ C B A ④C의 삽입 top→ C B A ⑤C의 삭제 top→ D B A ⑥D의 삽입
structure Stack objects : 0개 이상의 원소를 가진 유한 순서 리스트 functions : 모든 stack∈Stack, item∈element, max_stack_size∈positive integer ① Create. S(max_stack_size) = 최대 크기가 max_stack_size인 공백 스택을 생성 ② Is. FUll(stack, max_stack_size) = if(stack의 원소수==max_stack_size) return TRUE else return FALSE
③ Add(stack, item) = if(Is. Full(stack)) stack_full else stack의 톱에 item을 삽입하고 return ④ Is. Empty(stack) = if(stack==Create. S(max_stack_size)) return TRUE else return FALSE ⑤ Delete(stack) = if(Is. Empty(stack)) return else 스택 톱의 item을 제거해서 반환
스택 empty, full Stack Create. S(max_stack_size) = #define MAX_STACK_SIZE 100 /* 최대 스택 크기 */ typedef struct { int key; /* 다른 필드 */ } element; element stack[MAX_STACK_SIZE]; int top=-1; Boolean Is. Empty(Stack) = top<0; Boolean Is. Full(Stack) =top>=MAX_STACK_SIZE-1;
스택의 삽입 procedure ADD(item, STACK, n, top) if top≥n then call STACK-FULL top←top+1 STACK(top)←item end ADD top → C B A C 의 삽입
스택의 삭제 procedure DELETE(item, STACK, top) if top≤ 0 then call STACK-EMPTY item←STACK(top) top←top-1 end DELETE top → C B A C의 삭제
스택의 push, pop 스택의 push Void push(int *top, element node) { if (*top>=MAX_SIZE-1){ stack_full( ); return; } stack[++(*top)]=node; } 스택의 pop Element pop (int *top) { if (*top == -1) return stack_empty( ); return stack[(*top)--]; }
스택과 큐의 응용 분야 스택의 응용 분야 - 시스템 스택, 서브루틴 호출 - 인터럽트처리, 컴파일러 - 수식의 계산 - 순환 큐의 응용 분야 - 작업 스케줄링 - 버퍼 관리
스택의 응용(서브루틴 호출) prog MAIN call A r: end top → proc A call B s: end s r q proc B end
큐의 정의 QUEUE(1: n): 1차원 배열 형태 FIFO(First In First Out) 삽입 삭제 front rear
A f r 초기상태 A의 삽입 A B f B r f r B의 삽입 A의 삭제
structure Queue objects : 0개 이상 원소의 유한 순서 리스트 functions : 모든 queue∈Queue, item∈element, max_queue_size∈positive integer Create. Q(max_queue_size) : : = 최대 크기가 max_queue_size인 공백 큐를 생성 Is. Full. Q(queue, max_queue_size) : : = if(queue의 원소수==max_queue_size) return TRUE else return FALSE
Add. Q(queue, item): : = if(Is. Full(queue)) queue_full else queue의 뒤에 item을 삽입하고 이 queue를 반환 Is. Empty. Q(queue) : : = if(queue==Create. Q(max_queue_size)) return TRUE else return FALSE Delete. Q(queue) : : = if(Is. Empty(queue)) return else queue 앞의 item제거 및 반환
큐의 삽입 procedure ADDQ(item, Q, n, rear) if rear=n then call QUEUE-FULL rear←rear+1 Q(rear)←item A end ADDQ f B r
큐의 삭제 procedure DELETEQ(item, Q, front, rear) if front=rear then call QUEUE-EMPTY front←front+1 item←Q(front) B end DELETEQ f f r
순차 큐의 단점 D Q[1: 6] f rear=n 만원 큐 D f E F r
순차 큐의 문제점 front rear Q(1) Q(2) Q(3) Q(4) Q(5) . . Q(n) 설명 0 n J 1 J 2 J 3 J 4 J 5 . . Jn 초기 상태 1 n J 2 J 3 J 4 J 5 . . Jn J 1삭제 0 n J 3 J 4 J 5 J 6 . . Jn+1 삽입 1 n J 3 J 4 J 5 J 6 . . Jn+1 J 2삭제 0 n J 4 J 5 J 6 J 7 . . Jn+2 삽입 J 2 J 3 Queue-full 신호가 발생시 n-1개의 항목 을 모두 왼쪽shift 하는데 시간 낭비함.
순차큐에서의 삽입 삭제 front rear Q(0) Q(1) Q(2) Q(3) 설 명 -1 -1 -1 0 J 1 -1 1 J 2 -1 2 J 1 J 2 J 3 삽입 0 2 J 3 J 1 삭제 1 2 J 3 J 2 삭제 초기 상태 (큐 비어있음) J 1 삽입 J 2 삽입 Queue-full 의 최악의 경우 연산시간 O(n)
원형 큐의 삽입 procedure ADDQ(item, Q, n, rear) rear←(rear+1) mod n if front=rear then call QUEUE-FULL Q(rear)←item end ADDQ 65 27 35 0 f=0 r=3 35의 삽입 1 2 3 4
원형 큐의 삭제 procedure DELETEQ(item, Q, front, rear) if front=rear then call QUEUE-EMPTY front←(front+1) mod n item←Q(front) end DELETEQ 27 35 0 f=1 r=3 65의 삭제 1 2 3 4
65 27 35 0 1 2 3 f=0 r=0 초기상태 (공백 큐 상태) 4 52 27 35 0 1 2 f=1 r=3 65의 삭제 3 0 1 2 3 f=0 r=3 65, 27, 35의 삽입 4 0 4 27 35 48 1 2 f=1 r=0 48, 52의 삽입 (만원 큐 상태) 3 4
데크(deque) 리스트의 처음과 마지막 원소에 대해 삽입, 삭제 삽입 삭제 right left 삽입 삭제 삭제 스크롤(scroll) 삽입 쉘프(shelf)
데크의 삽입삭제 예 0 1 2 3 a 처음상태, l=2, r=3 4 b l에 c삽입, l=1, r=3 c a b r에 d삽입, l=1, r=4 c a b d l에 c삭제, l=2, r=4 5
수식의 표기법 중위 표기: A+B 전위 표기: +AB 후위 표기: AB+ h. A*(B+C) 전위: *A+BC 후위: ABC+*
후위 표기식의 연산 A*(B+C), A=3, B=4, C=5 ⇒ ABC+* 345+* t 3 3 4 5 t t 4 5 t 9 3 + t 27 *
②top← 0 //STACK을 초기화// ③loop ④ x←NEXT-TOKEN(E) ⑤ case ⑥ : x=‘∞’ : return //결과는 STACK(1)에// ⑦ : x is an operand: call ADD(x, STACK, n, top) ⑧ : else: call DELETE(OP 2, STACK, top) call DELETE(OP 1, STACK, top)
⑨ case ⑩ : x=‘+’: call ADD(OP 1+OP 2, STACK, n, top) ⑪ : x=‘-’: call ADD(OP 1 -OP 2, STACK, n, top) ⑫ : x=‘*’: call ADD(OP 1*OP 2, STACK, n, top) ⑬ : x=‘/’: call ADD(OP 1/OP 2, STACK, n, top) ⑭ : x=‘**’: call ADD(OP 1**OP 2, STACK, n, top) end forever
수식의 변환 A + (B - C) * D / E 중위→전위: (A + (((B - C) * D) / E)) 전위 + A / * - B C D E 중위→후위: (A + (((B - C) * D) / E)) 후위 A B C - D * E / +
후위 표기식 변환 과정 A*(B+C)∞ A A * -∞ -∞ * ( B + C -∞ * ( + ) -∞ * ∞ -∞ A A AB AB ABC+*
STACK(1)←’∞’: top← 1 loop x←NEXT-TOKEN(E) case : x=‘∞’ : while top> 1 do print(STACK(top)): top←top-1 end print(‘∞’) return : x is an operand: print(x)
: x=‘)’ : while STACK(top)≠’(‘do print(STACK(top)); top←top-1 end top←top-1 : else : while ISP(STACK(top)≥ICP(x) do print(STACK(top)): top←top-1 end call ADD(x, STACK, n, top) end forever
제 4장 연결 리스트
순서리스트의 삽입, 삭제 주소 원소 Lt Lt+1 Lt+2 Lt+3 Lt+4 Lt+5 Lt+6 월 화 목 금 일 수 금
연결리스트의 노드 구성 학번 성명 주소 데이터 노드 링크 학번 성명 주소
C언어에서의 동적 구조 구현 & : 주소연산자 * : 역 참조 연산자 int i, *pi; pi=&i; main() { Int *pi; pi=(int *)malloc(sizeof(int)); //동적메모리 할당. . 동적 기억장소 사용. . free(pi); }
포인터의 할당과 반환 int i, *pi; float f, *pf; pi=(int *)malloc(sizeof(int)); pf=(float *)malloc(sizeof(int)); *pi=1024; *pf=3. 14; printf("an integer = %d, a float = %fn", *pi, *pf); free(pi); free(pf);
단순 연결 리스트의 노드 주소 데이터 링크 1 금 5 2 목 1 3 4 5 6 7 8 F F 7 월 화 일 4 화 8 0 월 수 8 수 4 2 2 목 1 금 5 일 0
사용 공간과 비사용 기억 공간 주기억 장치 비사용 기억 공간 사용 공간 malloc(sizeof(X)) free(X)
단순 연결 리스트의 생성 procedure CREATE(T) call malloc(sizeof(I)) T←I; DATA(I)←’ 3304’ call malloc(sizeof(I)) LINK(T)←I LINK(I)←O; DATA(I)←’ 3308’ end CREATE I T 3304 3308 0
노드 삽입 I procedure INSERT(T, X) call malloc(sizeof(I)) DATA(I)←’ 3305’ if T = 0 then [T←I ; LINK(I)← 0] else [LINK(I)←LINK(X)] [LINK(X)←I] end INSERT 3305 X 3304 3308
노드 삭제 procedure DELETE(X, Y, T) if Y = 0 then T← LINK(T) else LINK(Y)←LINK(X) call free(X) end DELETE 3304 Y X 3305 3308
노드 출력 procedure PRINT(T) P←T while P≠ 0 do PRINT(DATA(P)) P←LINK(P) end PRINT 5 3304 T P 3305 3308 0 3 5 8
연결 리스트를 이용한 스택과 큐 <스택> 0 top <큐> 0 front rear
연결된 스택의 노드 추가 procedure ADDS(Y) call malloc(sizeof(X)) DATA(X)←Y LINK(X)←T T←X T X Y X end ADDS … … 0
연결된 스택에서 노드 삭제 procedure DELETES(Y) if T= 0 then call STACK-EMPTY X← T 저장 T Y Y ← DATA(X) X T ← LINK(X) call free(X) end DELETES … … 0
연결된 큐에 노드 추가 procedure ADDQ(Y) call malloc(sizeof(X)) DATA(X)←Y; LINK(X)← 0 if F=0 then [F←R←X] else [LINK(R)←X; R←X] end ADDQ X … F R Y 0
연결된 큐에서 노드 삭제 procedure DELETEQ(Y) if F=0 then call QUEUE-EMPTY else [X←F; F←LINK(X) Y←DATA(X); call free(X)] end DELETEQ Y X … F X R 0
찾아야 할 노드P T 2 15 … x 18 (a) 삽입 할 때 16 23 0 삽입 할 노드 X 찾아야 할 노드 T 2 … (b) 삭제 할 때 15 x P 16 x 18 삭제 할 노드 23 0
LLINK 데이터 RLINK LEFT 0 0 p p = RLINK(LLINK(p)) = LLINK(RLINK(p)) RIGHT
노드 삭제 L X procedure DDELETE(X, L) if X=L then call NO_MORE_NODES RLINK(LLINK(X)) ← RLINK(X) LLINK(RLINK(X)) ← LLINK(X) call free(X) end DDELETE
노드 삽입 … … p procedure DINSERT(P, X) LLINK(P) ← X RLINK(P) ← RLINK(X) LLINK(RLINK(X)) ← P RLINK(X) ← P end DINSERT
일반 리스트 A=(a 1, a 2, . . . , an)에서 A: 리스트의 이름, 대문자 표기 n: 리스트의 길이 a: 원소, 소문자 표기 n≥ 1인 경우 a 1을 A의 head, (a 2, . . . , an)을 A의 tail이라 함.
일반 리스트의 예 ① D=( ) ② A=( a, (b, c) ) ③ B=( A, A, ( ) ) ④ C=( a, C )
태그 필드를 사용한 리스트 표현 ① D=( ) D=0 ② A=(a, (b, c)) A 1 0 a 0 b ③ B=(A, A, ( )) ④ C=(a, C) 0 B C 1 00 1 1 0 a 0 c 0 1 0
다항식의 연결 리스트 표현 계수 COEF 14 지수 링크 EXP LINK 8 A=3 x + 2 x +1 A 3 14 2 8 1 0 0 -3 10 10 6 0 B=8 X 14 - 3 X 10+10 X 6 B 8 14
새로운 노드 첨가 알고리즘 procedure ATTACH(C, E, d) call malloc(sizeof(I)) EXP(I) ←E COEF(I) ←C LINK(d) ← I d←I end ATTACH I I … d C E
연결 리스트를 이용한 다항식 덧셈 procedure PADD(A, B, C) ①p←A; q←B ②call malloc(sizeof(C)); d←C
③while p≠ 0 and q≠ 0 do ④ case ⑤ : EXP(p)=EXP(q) ⑥ x←COEF(p)+COEF(q) ⑦ if x≠ 0 then call ATTACH(x, EXP(p), d) ⑧ p←LINK(p); q←LINK(q) ⑨ : EXP(p)<EXP(q) ⑩ call ATTACH(COEF(q), EXP(q), d) ⑪ q←LINK(q) ⑫ : else: call ATTACH(COEF(p), EXP(p), d) ⑬ p←LINK(p) ⑭ end
A=3 x 14 + 2 x 8 +1 A 2 8 3 14 B=8 X 14 - 3 X 10+10 X 6 B 8 14 C 11 14 -3 10 1 0 0 10 6 0
① while p≠ 0 do ② call ATTACH(COEF(p), EXP(p), d) ③ p←LINK(p) ④ end ⑤ while q≠ 0 do ⑥ call ATTACH(COEF(q), EXP(q), d) ⑦ q←LINK(q) ⑧ end ⑨ LINK(d)← 0; t←C; C←LINK(C) ⑩ call free(t) end PADD
procedure ERASE(T) if T=0 then return p←T while LINK(P)≠ 0 do p ← LINK(P) end LINK(P) ← AV AV ← T end ERASE AV T … P P 0 … 0
원형 연결 리스트 A= 3 x 14 + 2 x 8 + 1의 표현 A 3 14 2 8 1 0
procedure CERASE(T) if T=0 then return X ← LINK(T) ← AV AV ← X end CERASE T 3 14 AV X 2 8 … 1 0 0
헤드 노드를 가진 원형 연결 리스트 procedure CERASE 1(T) X ← LINK(T) ← AV AV ← X end CERASE 1 T - AV X 3 14 … 2 8 0
원형 리스트를 이용한 다항식 덧셈 procedure CPADD(A, B, C) p←LINK(A); q←LINK(B) call malloc(sizeof(C)); : EXP(C)←-1 d←C loop
case : EXP(p)=EXP(q): if EXP(p)=-1 then [LINK(d)←C; return] x←COEF(p)+COEF(q) if x≠ 0 then call ATTACH(x, EXP(p), d) p←LINK(p); q←LINK(q) : EXP(p)<EXP(q): call ATTACH(COEF(q), EXP(q), d) q←LINK(q) : else: call ATTACH(COEF(p), EXP(p), d) p←LINK(p) end forever end CPAAD
단순 연결 리스트의 역순 (a) X 13 9 5 20 (b) X 2 5 9 13 0
procedure INVERT(X) p←X; q← 0 while p≠ 0 do r ← q; q ← p p ← LINK(p) LINK(q) ← r end X←q end INVERT X 13 q=0 p 9 5 2 0
procedure INVERT(X) p←X; q← 0 while p≠ 0 do r ← q; q ← p p ← LINK(p) LINK(q) ← r end X←q end INVERT X 13 p r=0 q 9 5 2 0
procedure CONCATENATE(X, Y, T) Z←X if X=0 then [Z←Y; return] if Y=0 then return p←X while LINK(p)≠ 0 do p ← LINK(p) end LINK(p) ← Y end CONCATENATE Y X Z … P … 0
원형 연결 리스트의 앞에 노드 삽입 X 1 X X 3 X 2 X 1 X 2 X 3 A A
procedure INSERT-FRONT(A, X) if A=0 then [A←X LINK(X)←A] else [LINK(X)←LINK(A)←X] end INSERT-FRONT x X … A
원형 연결 리스트의 길이 계산 procedure LENGTH(A) i← 0 if A≠ 0 then [ptr←A repeat i←i+1; ptr←LINK(ptr) until ptr=A] return(i) end LENGTH
제 5장 트리
Tree의 정의 tree 는 하나이상의 노드로 구성된 유한집합으로서, (1) 특별히 지정된 노드인 루트(root)가 있고 (2) 나머지 노드들은 다시 각각이 트리 이면서 교차하지 않는 부분집합 T 1, T 2, …, Tm (m 0)으로 분할된다. 이때, T 1, T 2, …, Tm 을 루트의 부 트리(subtree)라고 부른다. A C B D I E F H G J K L M
T: A …… 1 T 2 B C T 21 T 12 T 13 G D E F H I J …… 2 …… 3 K …… 4 노드, 루트, 차수, 단말노드(리프), 자식노드, 부모(조상)노드, 형제노드, 레벨, 깊이
트리의 표현 1 A (A(B(D, E, F), C)) 3 C 2 B 6 F 4 5 D E 1 A 2 3 0 2 B 4 5 6 4 D 0 0 0 5 3 C 0 0 0 E 0 0 0 6 F 0 0 0
1 A 3 C 2 B 4 5 D E 0 A 6 F 1 0 C 0 0 B 0 D 0 E 0 F 0
순서 트리와 비순서 트리 A B A (a) A A B C D E (c) F (b) B D C B (d) F E
이진 트리의 추상화 구조 structure Binary_Tree (줄여서 Bin. Tree) objects: 공백이거나 루트 노드, 왼쪽 Binary_Tree, 오른쪽 Binary_Tree로 구성되는 노드들의 유한집합 functions: 모든 bt, bt 1, bt 2 ∈ Bin. Tree, item ∈ element Create() : : = 공백 이진 트리를 생성 Is. Empty(bt) : : = if (bt = = 공백 이진 트리) return TRUE else return FALSE
Make. BT(bt 1, item, bt 2) : : = 왼쪽 서브트리가 bt 1, 오른쪽 서브트리가 bt 2, 루트는 데이터를 갖는 이진 트리를 반환 Lchild(bt) : : = if (Is. Empty(bt)) return 에러 else bt의 왼쪽 서브트리를 반환 Data(bt) : : = if (Is. Empty(bt)) return 에러 else bt의 루트에 있는 데이터를 반환 Rchild(bt) : : = if (Is. Empty(bt)) return 에러 else bt의 오른쪽 서브트리를 반환
이진 트리의 레벨과 길이 …… 1(=20) A B D …… 2(=21) C E F G …… 3(=22)
포화 이진 트리와 완전 이진 트리 1 A A 3 2 B B C 4 D E F full G D C 5 E complete
보조 정리 5. 1 • 이진 트리의 level i 에서 최대 노드 수는 2 i-1 (i 1). root node의 level 이 0 일때 : 2 i (i 0) • 깊이가 k인 이진 트리의 최대 노드 수는 2 k - 1 (k 1). root의 depth가 0 일 때 : 2 k+1 - 1 (k 0)
보조 정리 5. 2 모든 이진 트리 T에 대해, n 0는 단말 노드수, n 2는 차수가 2인 노드수라 하면 n 0=n 2+1이다. n=n 0+n 1+n 2 n=1+n 1+2 n 2 n 0+n 1+n 2=1+n 1+2 n 2 n 0=n 2+1
보조 정리 5. 3 완전이진트리( complete binary tree)에서 i 번째 노드의 parent node는 int( i / 2 ) 에 위치한다. i 번째 노드의 LCHILD = 2*i (단, n 2*i ) RCHILD = 2*i + 1 (단, n 2*i +1) 1 A 3 2 B 4 D C 5 E F 6
이진 트리의 표현(배열) A B C A B D 1 2 3 4 A B C D 1 2 3 4 5 6 7 8 A B C D
이진 트리의 표현 (연결리스트) LCHILD DATA RCHILD A B DATA RCHILD LCHILD A C B 0 D 0 D 0 0 C 0
이진 트리의 순회1 순회방법: LDR, LRD, DLR, RDL, RLD, DRL 중위순회: LDR A 후위순회: LRD 전위순회: DLR B C
이진 트리의 순회2 B D H C E F I B G D H B C E F D G H I D-L-R 전위순회 G L-R-D 후위순회 DATA F I C E L-D-R 중위순회 DATA A
A B D C E F G 중위: 전위: A B D E C F G D B E A F C G 후위: D E B F G C A
중위순회 procedure INORDER(T) if T≠ 0 then [call INORDER(LCHILD(T)) print(DATA(T)) call INORDER(RCHILD(T))] end INORDER
pro IN(1) IN(2) P(A) pro IN(2) 1 IN(3) IN(4) A p(B) 3 2 IN(0) B 0 0 C 0 pro IN(4) 4 pro IN(3) IN(0) 0 D 0 IN(0) p(D) p(C) IN(0) D B A C IN(0)
이진 트리에 의한 정렬 X, X 30, Y, I, K, ZP, DST, A 30 X I DST A 30 X 30 K Y ZP INORDER(T) 적용 : A 30, DST, I, K, X, X 30, Y, ZP
명제식 논리 변수: x 1, x 2, x 3 연산자: ∧, ∨, ┐ x 1, x 3: true, x 2: flase ∧ ∨ (┐x 1∨x 2)∧x 3 ┐ X 3 X 2 X 1
procedure POSTORDER-EVAL(T) ① if T≠ 0 then LCHILD DATA VAL RCHILD [call POSTORDER-EVAL(LCHILD(T)) ② call POSTORDER-EVAL(RCHILD(T)) ③ Case ④ : DATA(T)=‘┐’: VAL(T)←not VAL(RCHILD(T)) ⑤ : DATA(T)=‘∨’: VAL(T)←VAL(LCHILD(T)) or VAL(RCHILD(T)) ⑥ : DATA(T)=‘∧’: VAL(T)←VAL(LCHILD(T)) and VAL(RCHILD(T)) ⑦ : else VAL(T)←DEF(DATA(T)) ⑧ end] end POSTORDER-EVAL
논리 변수: x 1, x 2, x 3 연산자: ∧, ∨, ┐ x 1, x 3: true, x 2: flase ∧ (┐x 1∨x 2)∧x 3→flase ∨ f f t f ┐ X 2 X 1 f X 3
스레드 이진 트리 1 A B A C B D D C
스레드 이진 트리 LTAG LLINK DATA RLINK RTAG 0 : LLINK = 스레드 포인트 LTAG = 1 : LLINK = 정상 포인트 0 : RLINK = 스레드 포인트 RTAG = 1 : RLINK = 정상 포인트
스레드 이진 트리 HEAD 1 1 0 1 0 B D 0 A 1 1 1 C 0
스레드 이진 트리 procedure INSUC(X) S←RCHILD(X) If RBIT(X) = 1 then [while LBIT(S) = 1 do S←RCHILD(X) end] return(s) end INSUC
스레드 이진 트리 procedure TINORDER(T) HEAD←T loop T←INSUC(T) If T = HEAD then return print(DATA(T)) forever end TINORDER
트리의 이진 트리 변환 * 보조 정리 5. 4 N개의 노드를 갖고, 차수가 k인 트리(kary tree)t를 k개의 링크 영역을 갖는 노드 형태로 저장할 때 전체 링크 수 n*k 널 링크 수 = 전체 – 널이 아닌 링크 = nk - (n-1) = n(k-1) + 1
A B D E F G A C C B H A G H C D E I F I B I E D G 삼진트리를 이진 트리로 변환하는 과정 F H
히프 추상 데이터 타입 • 최대 트리(max tree)는 각 노드의 키 값이(자식이 있다면) 그 자식의 키 값보다 작지 않은 트리이다. 최대 히프(max heap)는 최대 트리인 완전 이진 트리이다. • 최소 트리(min tree)는 각 노드의 키 값이(자식이 있다면) 자식의 키 값보다 크지 않은 트리이다. 최소 히프(min heap)는 최소 트리이면서 완전 이진 트리이 다.
최대 히프의 예 14 12 10 7 8 30 9 6 6 5 3 25
최소 히프의 예 2 7 10 10 4 8 20 50 11 83 21
최대 히프에서의 삽입 20 20 15 14 2 15 10 14 (a) 삽입전의 히프 10 (b) 새로운 노드의 초기 위치 20 15 14 2 15 5 10 2 (c) 히프 (a)에 5를 삽입 21 14 5 10 2 (d) 히프 (a)에 21을 삽입
이진 탐색 트리 정의 : 이진 탐색 트리는 공백이 가능한 이진 트리이다. 만약 공백이 아니라면 다음 성질을 만족한다. 1) 모든 원소는 키를 가지며, 어떤 두 원소도 동일한 키를 갖지 않는다. 즉 키는 유일한 값을 가진다. 2) 공백이 아닌 좌측 서브트리에 있는 키들은 그 서 브트리의 루트의 키보다 작아야 한다. 3) 공백이 아닌 우측 서브트리에 있는 키들은 그 서 브트리의 루트의 키보다 커야 한다. 4) 좌측과 우측 서브트리도 이진 탐색 트리이다.
이진 탐색 트리 Procedure SEARCH(tree, key) while tree 0 do if key = data(tree) then return (tree); if key < data(tree) then left-child(tree) else right-child(tree); return(null); end SERCH
procedure insert_node(tree, num) temp ← modified_search(tree, num) if(temp ≠ 0 or tree=0) then[ if ptr = IS_FULL then[print(The memory is full); exit ] data(ptr) ← num; right-child(ptr) ← NULL; left-child(ptr) ← NULL; if tree ≠ 0 then [ if num <data(temp) then left-child(left) ← ptr; else right-child(temp) ← ptr; ] else tree ← ptr; ] end insert-node
이진 탐색 트리의 삽입 30 30 5 2 80 (a) 80의 삽입 40 5 40 2 35 (b) 35의 삽입 80
이진 탐색 트리의 삭제 40 40 60 55 20 55 55 20 10 50 30 70 55 55 45 52 55 (a) 60을 삭제하기전의 트리 45 52 55 (a) 60을 삭제한 후의 트리
1 K=8인 선택 트리 2 3 6 8 4 5 9 8 6 6 8 6 9 10 7 11 12 17 13 14 15 10 9 20 6 8 9 90 17 15 20 20 15 15 11 100 18 16 38 30 25 50 16 110 20 run 1 run 2 run 3 run 4 run 5 run 6 run 7 run 8
포리스트의 이진 트리 변환 정의 : T 1, T 2, ‥ , Tn 트리들로 이루어진 포리스트가 있 다면 이 포리스트에 대응하는 이진 트리는 B(T 1, T 2, ‥ , Tn )으로 표시되며, 1) n = 0 이면 B는 공백이다. 2) B는 T 1 과 같은 루트를 가지며, 좌측 서브트리로 B(T 11, T 12, ‥ , T 1 m ) 를 가진다. (단, T 11, T 12, ‥ , T 1 m은 T 1(루트)의 서브트리들이다). 그리고 우측 서브트리는 B( T 2, ‥ , Tn )이다.
3개의 트리로 구성된 포리스트 이진 트리 표현 E A A B C D F G H I B E C F D G H I
서로 다른 이진 트리 n=2 n=3
스택 순열 전위 : ABCDEF 중위 : BCAEDF A A D, E, F B, C (a) D, E, F B C (b)
전위 : ABCDEF 중위 : BCAEDF A 1 B D C E 2 F 4 3 5 6 (c)의 노드에 번호를 부여한 이진 트리
ed6f8819857b110a382560fa4b9acbdc.ppt