1. 시험계 - nifds.go.kr · - 개와 원숭이 등 : 글자를 새기거나(문신 등) 혹은 목에 표찰(tag)을 부착 - 단기간시험 : 색소도포 이용, 사용할 색소는
자료구조 강의노트 -...
Transcript of 자료구조 강의노트 -...
소프트웨어학과 원성현 교수 1
자료구조 강의노트
교재 : C로 배우는 쉬운 자료구조(개정판) 출판사 : 한빛미디어(2011년 3월 발행) 저자 : 이지영
소프트웨어학과 원성현 교수 19
3장 자료구조 구현을 위한
C프로그래밍 기법
소프트웨어학과 원성현 교수 20
1. 배열
• 배열(array)이란? • 같은 데이터 타입을 가진 여러 개의 데이터를 연속으로 저장할 수 있는 데이터 구조
• 1차원 배열(1-dimensional array) • 데이터가 저장되는 방향의 개수가 1개인 배열
• 1차원 배열의 선언 • int a[5];
1차원 배열
자료형 배열이름[배열의 크기]
char c[100]; int i[100]; short s[100]; long l[100];
의미 문자형 100개 정수형 100개 짧은 정수형 100개 긴 정수형 100개
배열요소 c[0]~c[99] i[0]~i[99] s[0]~s[99] l[0]~l[99]
메모리 할당 1바이트× 100개 4바이트× 100개 2바이트× 100개 4바이트× 100개
소프트웨어학과 원성현 교수 21
• 1차원 배열의 초기화 • int a[5] = {1, 2, 3, 4, 5};
• 선언한 배열 요소의 수와 실제 데이터의 수가 일치되는 경우는 정확하게 데이터가 순서대로 저장 • a[0]=1, a[1]=2, a[2]=3, a[3]=4, a[4]=5
• int a[] = {1, 2, 3, 4, 5}; • 배열 요소의 수를 선언하지 않고 배열 타입과 이름만 선언한 후 데이터를 저장한 경우는 데이터의 수만큼 배열의 크기가 만들어짐 • a[0]=1, a[1]=2, a[2]=3, a[3]=4, a[4]=5
• int a[5] = {1, 2, 3}; • 선언한 배열 요소의 수보다 적은 데이터를 저장하는 경우는 데이터를 저장하고 남는 공간에는 0이 저장 • a[0]=1, a[1]=2, a[2]=3, a[3]=0, a[4]=0
• int a[3] = {1, 2, 3, 4, 5}; • 선언한 배열 요소의 수보다 많은 데이터를 저장하는 경우는 순서대로 데이터를 저장하고 남는 데이터는 없어짐 • a[0]=1, a[1]=2, a[2]=3
소프트웨어학과 원성현 교수 22
• 문자 배열 • 문자와 문자열
• 문자는 한 글자를 말하고 문자열은 2개 이상의 문자가 나열된 것을 말함 • 문자는 작은 따옴표(‘’), 문자열은 큰 따옴표(“”)에 표기 • 문자 배열과 문자열은 같은 말
• 문자 배열(문자열)의 초기화 • char s1[10] = “String”; 또는 char s1[] = {‘S’, ‘t’, ‘r’, ‘i’, ‘n’, ‘g’, ‘\0’};
• s1[0]=‘S’, s1[1]=‘t’, s1[2]=‘r’, s1[3]=‘i’, s1[4]=‘n’, s1[5]=‘g’, s1[6]=‘\0(null)’, s1[7]~s1[9]=데이터 없음
• char s2[10] = {‘S’, ‘t’, ‘r’, ‘i’, ‘n’, ‘g’}; • s2[0]=‘S’, s2[1]=‘t’, s2[2]=‘r’, s2[3]=‘i’, s21[4]=‘n’, s2[5]=‘g’, s2[6]~s2[9]=데이터 없음
• 문자열과 문자의 특징 비교 • 문자열로 저장하는 경우는 마지막 문자 다음에 반드시 null 문자가 저장되기 때문에 기억 공간은 데이터의 수보다 1개 더 많음 • 문자로 저장하는 경우는 데이터의 수만큼만 기억 공간이 있으면 됨
소프트웨어학과 원성현 교수 23
• 다차원 배열(multi-dimensional array) • 2차원(2-dimension) 이상의 배열을 의미하고, 데이터가 저장되는 방향이 2개 이상임 • 2차원 배열의 경우는 행(row)과 열(column), 3차원 배열의 경우는 면(frame)과 행(row)과 열(column)로 나타냄
• 2차원 배열의 선언 • int a[2][3];
다차원 배열
자료형 배열이름[배열의 행의 크기][배열의 열의 크기]
a[0][0] a[0][1] a[0][2]0
a[1][0] a[1][1] a[1][2]
행번호 0
행번호 1
열번호 0 열번호 1 열번호 2
a[0][0]
a[0][1]
a[0][2]0
a[1][0]
a[1][1]
a[1][2]
주기억장치에 저장되는 순서
소프트웨어학과 원성현 교수 24
• 3차원 배열의 선언 • int a[2][3][4];
자료형 배열이름 [배열의 면의 크기][배열의 행의 크기][배열의 열의 크기]
a[0][0] a[0][1] a[0][2]
a[1][0] a[1][1] a[1][2]
행번호 0
행번호 1
열번호 0 열번호 1 열번호 2
a[2][0] a[2][1] a[2][2] 행번호 2
a[0][3]
a[1][3]
열번호 3
a[2][3]
면번호 0
a[0][0] a[0][1] a[0][2]
a[1][0] a[1][1] a[1][2]
a[2][0] a[2][1] a[2][2]
a[0][3]
a[1][3]
a[2][3]
면번호 1
a[0][0][0]
a[0][0][1]
a[0][0][2]
a[0][0][3]
a[0][1][0]
a[0][1][1]
a[0][1][2]
a[0][1][3]
a[0][2][0]
a[0][2][1]
a[0][2][2]
a[0][2][3]
a[1][0][0]
a[1][0][1]
a[1][0][2]
a[1][0][3]
~~~
주기억장치에 저장되는 순서
소프트웨어학과 원성현 교수 25
• 2차원 배열의 초기화 • int a[2][3] = {{1, 2, 3}, {4, 5, 6}}; 또는 int a[][3] = {{1, 2, 3}, {4, 5, 6}}; 또는 int a[][3] = {1, 2, 3, 4, 5, 6};
• 행의 배열 크기만 생략 가능 • 3차원 배열의 초기화
• int a[2][3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24}};
1 2 3
5 6 7
행번호 0
행번호 1
열번호 0 열번호 1 열번호 2
9 10 11 행번호 2
4
8
열번호 3
12
면번호 0
13 14 15
17 18 19
21 22 23
16
20
24
면번호 1
소프트웨어학과 원성현 교수 26
• 문자 다차원 배열 • char a[3][20];
• 20개의 문자를 저장할 수 있는 3개의 1차원 배열 생성 • char a[3][20] = {“Hong Gil Dong”, “Computer Department”, “Seoul Korea”};
• strcpy(c[0], “Hong Gil Dong”); • strcpy(c[1], “Computer Department”); • strcpy(c[2], “Seoul Korea”);
H o n g G i l D o n g \0
C o m p u t e r D e p a r t m e n t \0
S e o u l K o r e a \0
[0]
[1]
[2]
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19]
소프트웨어학과 원성현 교수 27
2. 포인터
포인터 선언
• 포인터(pointer) 변수란? • 데이터를 저장하지 않고, 데이터가 저장된 기억공간 상의 주소를 저장하는 변수 • 기억공간의 주소를 지정하므로 일반적으로 2바이트 공간을 사용
• 포인터 변수 사용 예 • int i; • *ptr = &i;
데이터 10 150
주소 : 150
변수 ptr 변수 i
자료형 *포인터 변수 이름
char *ptr; short *ptr; int *ptr;
포인터 변수 ptr이 지정하는 주소로 가보면 문자 1개가 저장되어 있음
포인터 변수 ptr이 지정하는 주소로 가보면 정수 데
이터가 저장되어 있음
소프트웨어학과 원성현 교수 28
포인터 연산
• 주소 연산자 • 주소 연산자 &는 변수의 주소를 얻는데 사용 • 주소 연산자 사용 예
• int i=10; ---------- ① • int *ptr; ---------- ② • ptr=&i; ---------- ③
데이터 10
주소 : 150
변수 ptr 변수 i
주소 : 160
데이터 10 150
변수 ptr 변수 i
① ②
주소 : 150 주소 : 160
③
소프트웨어학과 원성현 교수 29
• 참조 연산자 • 참조 연산자 *는 저장된 주소에 있는 값을 사용할 수 있음 • 참조 연산자 사용 예
• int i, j; • int *ptr; • ptr=&i; ---------- ① • *ptr=10; --------- ② • j=*ptr; ---------- ③
주소 : 154
변수 i 변수 j
주소 : 150
150
변수 ptr
①
주소 : 160
데이터 10
주소 : 154
변수 i 변수 j
주소 : 150
150
변수 ptr
주소 : 160
데이터 10 데이터 10
주소 : 154
변수 i 변수 j
주소 : 150
150
변수 ptr
주소 : 160
② ③
소프트웨어학과 원성현 교수 30
• 포인터 변수에 초기 값을 주는 것은 인위적으로 이루어지는 것이 아니라 시스템적으로 이루어짐 • 초기화하는 방법
• 주소 연산자 &를 사용하여 변수의 주소 지정 • int i; • int *ptr=&i; 또는
• 동적 메모리를 할당하고 시작 주소를 포인터 값으로 지정 • char *ptr=(char *)malloc(100); 또는
• 문자형 포인터에 문자열의 시작 주소를 지정 • char *ptr=“korea”; 또는
• 배열의 이름을 이용하여 배열 시작 주소를 지정 • char a[100]; • char *ptr=a; 또는
• 배열의 첫번 째 요소의 주소를 이용하여 배열 시작 주소를 지정 • char a[100]; • char *ptr=&a[0];
포인터의 초기화
소프트웨어학과 원성현 교수 31
• 포인터에 배열의 시작 주소를 지정하기 위해서는 배열 이름을 포인터에 전달하거나 첫 번째 배열 요소의 주소를 포인터에 전달
• char string1[20]=“Dreams come true!”, string2[20], *ptr1, *ptr2; • ptr1=&string1[0];
포인터와 문자열
D r e a m s c o m e t r u e ! \0 string1
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19]
변수 ptr1
변수 ptr1+1
변수 ptr1+2
• 포인터의 포인터 • char **ptr;
변수 ptr
소프트웨어학과 원성현 교수 32
• 여러 개의 포인터를 하나의 배열로 구성한 것으로 배열의 특징과 포인터의 특징을 모두 활용한 데이터 구조
• 자료형 *포인터배열명[배열크기]; • char string[3][10] = {“Dreams”, “come”, “true!”}; • char *ptr[3] = {{“Dreams”}, {“come”}, {“true!”}}
포인터 배열
string[0]
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
D r e a m s \0
c o m e \0
t r u e ! \0
string[1]
string[2]
ptr[0] D r e a m s \0
c o m e \0
t r u e ! \0
ptr[1]
ptr[2]
메모리 낭비 요소
소프트웨어학과 원성현 교수 33
3. 구조체
구조체 선언
• 구조체(struct)란? • 배열이 여러 개의 동일한 타입의 데이터만 저장할 수 있는 것에 반해서 구조체는 서로 다른 데이터 타입을 저장할 수 있는 데이터 구조
김선달 2004 2700
이몽룡 2003 3200
홍길동 2005 2400
향단이 2004 2900
성명 입사연도 연봉
레코드
파일
필드
struct 구조체 이름 { 자료형 항목 1; 자료형 항목 2; ~ 자료형 항목 n; }; struct employee { char name[10]; int year; int pay; }; struct employee Lee;
name year pay
employee
10바이트 4바이트 4바이트
소프트웨어학과 원성현 교수 34
구조체의 초기화
• 구조체 선언 방법 • 구조체를 선언하고 그 다음에 구조체 변수를 선언하는 방법 • 구조체와 구조체 변수를 동시에 선언하는 방법 • 구조체 이름을 생략하고 구조체 변수만 선언하는 방법
struct employee { char name[10]; int year; int pay; }; struct employee Lee;
struct { char name[10]; int year; int pay; }; Lee;
struct employee { char name[10]; int year; int pay; } Lee;
• 구조체 초기화 방법 • 구조체는 여러 개의 필드를 가지므로 필드의 자료형과 수에 맞게 {}를 이용하여 순서대로 지정
• struct employee Lee={“Ann”, 2005, 3200};
A n n \0 2005 3200 Lee
소프트웨어학과 원성현 교수 35
데이터 항목의 참조
• 구조체 연산자 • 점 연산자(.)
• 구조체 변수의 필드를 지정 • 화살표 연산자(->)
• 구조체형 포인터에서 포인터가 가리키는 구조체 변수의 필드를 지정
struct employee Lee; Lee.name=“Ann”; Lee.year=2005; Lee.pay=3200;
A n n \0 2005 3200 Lee
struct employee Kim; struct employee *Sptr=&Kim; Sptr->name=“susan”; Sptr->year=2004; Sptr->pay=3400;
s u s a n \0 2004 3400 Kim
sptr
name[10] year pay
name[10] year pay
소프트웨어학과 원성현 교수 36
구조체의 연산
• 데이터 항목 참조 연산
struct employee Lee; struct employee *Sptr; Sptr=&Lee; Lee.year=2005; Sptr->pay=3000; Sptr->name=“Ann”;
• 구조체 복사 연산
struct employee Lee, Kim, team[5]; Lee=kim; Lee=team[2]; Team[2]=team[3];
• 구조체 변수의 주소 구하기 연산
struct employee Lee, team[5]; struct employee *Sptr1, *Sptr2; Sptr1=&Lee; Sptr2=team;
소프트웨어학과 원성현 교수 37
4. 재귀호출
순환
• 순환(recursion)이란? •어떤 알고리즘이나 함수가 자기 자신을 호출하여 문제를 해결하는 프로그래밍 기법.
• 팩토리알 계산
int factorial(int n) { if(n<=1) return(1); else return(n*factorial(n-1)); }
int factorial_iter(int n) { int k, v=1; for(k=n; k>0; k--) v=v*k; return(v); }
순환 반복
소프트웨어학과 원성현 교수 38
factorial(3) { if(3<=1) return 1; else return(3*factorial(3-1)); }
factorial(2) { if(2<=1) return 1; else return(2*factorial(2-1)); }
factorial(1) { if(1<=1) return 1; else return(1*factorial(1-1)); }
• factorial(3)의 순환 과정
소프트웨어학과 원성현 교수 39
• 순환 알고리즘의 성능 • 장점
• 프로그래밍하기 용이함 • 이해하기 용이함 • 때로는 순환을 사용하지 않는 경우 프로그래밍이 불가능한 경우도 있음
• 단점 • 수행 시간이 더 요구됨 • 순환 호출시에는 호출이 일어날 때마다 호출하는 함수의 상태를 기억해야 하므로 기억 공간의 비효율적인 사용