반응형

1. Figure 1 and 2 show the recursive traversal algorithms(or programs) of preorder and postorder, respectively. Write the respectively corresponding iterative traversal algorithms(or programs) of preorder and postorder.

<Figure 2. Postorder traversal algorithm>


<Figure 1. Preorder traversal algorithm>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <stdio.h>
#include <stdlib.h> //exit 함수 사용때문에 넣음
 
#define MAX_STACK_SIZE 10 //스택 최대 크기
 
typedef struct node* treepointer;  //node 자료형 포인터의 새로운 이름 treepointer
typedef struct node{
    char data;
    treepointer leftchild, rightchild;
}node; //node 구조체 자료형의 새로운 이름 node, 안에는 char형 data와 treepointer형 leftchild, rightchild가 들어있다.
 
void push(treepointer stack[],treepointer item,int *top);
treepointer pop(treepointer stack[],int *top);
void iterpreorder(treepointer node);
void iterpostorder(treepointer node);
 
 
int main(void)
{
    int i; // int형 변수 i
    treepointer root; //treepointer 형 포인터 변수 root
    node tree[MAX_STACK_SIZE]; // node 배열 tree 크기는 10
    for(i=0;i<MAX_STACK_SIZE;i++//i=0부터 10보다 작을때까지 반복
    {tree[i].leftchild=0; tree[i].rightchild=0;tree[i].data=0;} //배열의 원소 초기화
    tree[0].data='+'; tree[0].leftchild=&tree[1]; tree[0].rightchild=&tree[2]; 
    tree[1].data='*'; tree[1].leftchild=&tree[3]; tree[1].rightchild=&tree[4]; 
    tree[2].data='E'
    tree[3].data='*'; tree[3].leftchild=&tree[5]; tree[3].rightchild=&tree[6]; 
    tree[4].data='D';
    tree[5].data='/'; tree[5].leftchild=&tree[7]; tree[5].rightchild=&tree[8]; 
    tree[6].data='C';
    tree[7].data='A';
    tree[8].data='B'//문제에서와 같이 바이너리 트리 형성
    root=&tree[0];  //root에 tree[0]의 주소 대입 (첫번째 노드)
    printf("preorder : ");iterpreorder(root); //preorder를 itr로 구현한 함수 호출
    printf("postorder : ");iterpostorder(root);//postorder를 itr로 구현한 함수 호출
    return 0;
}
 
void push(treepointer stack[],treepointer item,int *top)
{
    if(*top>=MAX_STACK_SIZE-1//만약에 top이가리키는주소의 값이 9이상이라면 
        {fprintf(stderr,"스택 과부하 원소 추가 불가능\n"); // 문장 출력하고
    exit(EXIT_FAILURE);} //프로그램 종료
    stack[++(*top)]=item; //stack의 맨 위에 item 삽입
}
treepointer pop(treepointer stack[],int *top)
{
    if((*top)==-1//top이 가리키는 주소의 값이 -1 이라면
    {fprintf(stderr,"스택 비어있음\n"); //문장 출력하고
    exit(EXIT_FAILURE);} //프로그램 종료
    return stack[(*top)--]; //제일 위에 있는 원소 return
}
 
void iterpreorder(treepointer node)
{
    int top=-1//int 형 변수 top을 -1로 초기화
    treepointer stack[MAX_STACK_SIZE]; //treepointer 형 포인터배열 stack 크기는 10
    push(stack,node,&top); //node를 stack에 쌓는다.
    while(1){
        if(top==-1break//top이 -1이면 루프 탈출 어차피 마지막이 아니면 top이 -1이 될 일이 없다.
        node=stack[top]; //node에 stack의 top 원소 삽입
        printf("%c", node->data); //node의 data 출력
        pop(stack,&top); //stack의 top원소 pop
        if(node->rightchild) //node가 가리키는 구조체node에 rightchild가 있으면
            push(stack,node->rightchild,&top); //stack에 쌓는다.
        if(node->leftchild) //node가 가리키는 구조체node에 leftchild가 있으면
            push(stack,node->leftchild,&top); //stack에 쌓는다.
        }
    printf("\n"); //개행문자 출력
    }
void iterpostorder(treepointer node)
{
    int top1=-1//int 형 변수 top1을 -1로 초기화
    int top2=-1//int 형 변수 top2을 -1로 초기화
    treepointer stack1[MAX_STACK_SIZE]; //treepointer 형 포인터배열 stack1 크기는 10
    treepointer stack2[MAX_STACK_SIZE]; //treepointer 형 포인터배열 stack2 크기는 10
    push(stack1,node,&top1); //node를 stack1에 쌓는다.
    while(1)
    {
        if(top1==-1)break//top1이 -1이면 루프 탈출  어차피 마지막이 아니면 top1이 -1이 될 일이 없다.
        node=pop(stack1,&top1); //node에 stack에서 pop한 원소를 대입
        push(stack2,node,&top2); // stack2에 node를 삽입
        if(node->leftchild) //node가 가리키는 구조체node에 leftchild가 있으면
            push(stack1,node->leftchild,&top1); //stack1에 쌓는다.
        if(node->rightchild) //node가 가리키는 구조체node에 rightchild가 있으면
            push(stack1,node->rightchild,&top1); //stack1에 쌓는다.
    }
    while(1)
    {
        if(top2==-1)break;  //top2가 -1이면 루프 탈출  어차피 마지막이 아니면 top2가 -1이 될 일이 없다.
        node=pop(stack2,&top2); //node에 stack2에서 pop한 원소 대입
        printf("%c", node->data); //character type으로 출력 
    }
    printf("\n"); //개행문자 출력
    }
 
cs



2. Write a C function that searches for an arbitrary element in a max heap. What is the computing time of your function?

<Figure 3. Max heap>



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
 
#define MAX_SIZE 8 //스택 최대 크기
 
typedef struct node* treepointer;  //node 자료형 포인터의 새로운 이름 treepointer
typedef struct node{
    int data;
    treepointer leftchild, rightchild;
}node; //node 구조체 자료형의 새로운 이름 node, 안에는 char형 data와 treepointer형 leftchild, rightchild가 들어있다.
 
void search_max_heap(treepointer ptr,treepointer *res,int value);
 
int main(void)
{
    int i; // int형 변수 i
    treepointer root; //treepointer 형 포인터 변수 root
    treepointer res=0//결과 값을 저장할 treepointer res
    node tree[MAX_SIZE]; // node 배열 tree 크기는 10
    for(i=0;i<MAX_SIZE;i++//i=0부터 10보다 작을때까지 반복
    {tree[i].leftchild=0; tree[i].rightchild=0;tree[i].data=0;} //배열의 원소 초기화
    tree[0].data=14; tree[0].leftchild=&tree[1]; tree[0].rightchild=&tree[2]; 
    tree[1].data=12; tree[1].leftchild=&tree[3]; tree[1].rightchild=&tree[4]; 
    tree[2].data=7;  tree[2].leftchild=&tree[5];
    tree[3].data=10
    tree[4].data=8;
    tree[5].data=6;  //교과서와 같이 트리 생성
    root=&tree[0];  //root에 tree[0]의 주소 대입 (첫번째 노드)
    printf("번호    값    주소\n");
    for(i=0;i<MAX_SIZE;i++)
    {printf("[%d]번 노드 : %d    %d\n",i,tree[i].data,&tree[i]);} //트리의 각 노드 값과 주소 출력
    search_max_heap(root,&res,10); //서치 펑션 호출, 10을 찾음
    printf("찾은값    해당주소\n"); 
    printf("%d    %d\n",res->data,res); //찾고싶은 값의 주소와 값을 가리키는 res 출력
    
    return 0;
}
 
void search_max_heap(treepointer ptr,treepointer *res,int value)
{
    if(ptr){ //ptr이 NULL이 아니면
    if(ptr->data==value)  //ptr이 가리키는 data가 value와 같으면
        *res=ptr; //res가 가리키는 포인터에 ptr의 주소 대입
    else if(((ptr->data)>value)){ //ptr->data가 value보다 크면
        search_max_heap(ptr->leftchild,res,value); //ptr->leftchild로 서치 펑션 재귀적 호출
        search_max_heap(ptr->rightchild,res,value);} //ptr->rightchild로 서치 펑션 재귀적 호출
    else if((ptr->data)<value){ //ptr->data가 value보다 작으면
        printf("%d는 %d보다 작다.\n",ptr->data,value); //아무것도 안해도 되지만 디버깅 위해 문장 출력
    }}
    
}
cs



3. Write the swapTree function of C that swap left child and right child of all nodes.

<Figure 4. swapTree>



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <stdio.h>
#define MAX_SIZE 10 //스택 최대 크기
 
typedef struct node* treepointer;  //node 자료형 포인터의 새로운 이름 treepointer
typedef struct node{
    char data;
    treepointer leftchild, rightchild;
}node; //node 구조체 자료형의 새로운 이름 node, 안에는 char형 data와 treepointer형 leftchild, rightchild가 들어있다.
 
 
void swap_bin_tree(treepointer ptr);
void print(treepointer ptr);
 
int main(void)
{
    int i; // int형 변수 i
    treepointer root; //treepointer 형 포인터 변수 root
    node tree[MAX_SIZE]; // node 배열 tree 크기는 10
    for(i=0;i<MAX_SIZE;i++//i=0부터 10보다 작을때까지 반복
    {tree[i].leftchild=0; tree[i].rightchild=0;tree[i].data=0;} //배열의 원소 초기화
    tree[0].data='A'; tree[0].leftchild=&tree[1]; tree[0].rightchild=&tree[2]; 
    tree[1].data='B'; tree[1].leftchild=&tree[3]; tree[1].rightchild=&tree[4]; 
    tree[2].data='C'; tree[2].leftchild=&tree[5];
    tree[3].data='D';                              tree[3].rightchild=&tree[6]; 
    tree[4].data='E';
    tree[5].data='F';                              tree[5].rightchild=&tree[7]; 
    tree[6].data='G';
    tree[7].data='H'//교과서와 같이 이진 트리 구현
    root=&tree[0];  //root에 tree[0]의 주소 대입 (첫번째 노드)
    printf("번호    값    주소\n");
    for(i=0;i<MAX_SIZE;i++)
    {printf("[%d]번 노드 : %c    %d\n",i,tree[i].data,&tree[i]);} //각 노드의 값과 주소 출력
    swap_bin_tree(root); //트리 스왑
    print(root); //스왑된 트리 확인
    return 0;
}
 
void swap_bin_tree(treepointer ptr)
{
    treepointer temp; //treepointer 즉 node의 포인터 temp
    if(ptr){ //ptr이 NULL이아니면 
        temp=ptr->leftchild;  
        ptr->leftchild=ptr->rightchild;
        ptr->rightchild=temp; //temp라는 빈 물 컵을 이용해 left와 right의 스왑
        
        if(ptr->leftchild) //leftchild가 null이 아니면 (불필요한 반복 줄이기 위해 한번 더 검사)
    swap_bin_tree(ptr->leftchild); //스왑
        if(ptr->rightchild) //rightchild가 null이 아니면 (불필요한 반복 줄이기 위해 한번 더 검사)
    swap_bin_tree(ptr->rightchild); //스왑
    }}
void print(treepointer ptr)
{
    if(ptr){
    printf("노드             : %c    %d\n",ptr->data,ptr); //노드 값, 주소 출력
    if(ptr->leftchild) //ptr->leftchild가 NULL이 아니면 (불필요한 반복 줄이기 위해 한번 더 검사)
    printf("노드 왼쪽 자식   : %c    %d\n",(ptr->leftchild)->data,ptr->leftchild); //노드 왼쪽 자식 값, 주소 출력
    if(ptr->rightchild) //ptr->rightchild가 NULL이 아니면 (불필요한 반복 줄이기 위해 한번 더 검사)
    printf("노드 오른쪽 자식 : %c    %d\n",(ptr->rightchild)->data,ptr->rightchild); //노드 오른쪽 자식 값, 주소 출력
    if(ptr->leftchild) //ptr->leftchild가 NULL이 아니면
    print(ptr->leftchild); // 재귀호출 프린트
        if(ptr->rightchild) //ptr->rightchild가 NULL이 아니면
    print(ptr->rightchild); //재귀호출 프린트
    }
}
cs







반응형
반응형

1. Using the binary search function, show the status of the system stack diagram such as below the example after each function call for the iterative and recursive function.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define COMPARE(mid,searchnum)  (((mid)<(searchnum)) ? (1) : (((mid)>(searchnum)) ? (-1) : (0)))  //미들값과 찾는값의 크기를 비교하여 해당 값 반환
/* mid<searchnum 이면 -1 반환, mid>searchnum이면 1 반환, mid=searchnum이면 1 반환*/
#define MAX_SIZE 1001 //상수 MAX_SIZE는 1001
#define ITERATIONS 16 //상수 ITERATIONS는 16
int count=0;
int binsearch_rec(int list[], int searchnum, int left, int right);
int binsearch_itr(int list[], int searchnum, int left, int right);
int main(void)
{
    int i;
    int list[MAX_SIZE]; //int형 배열 list 선언, 배열의 크기는 MAX_SIZE=1001
    for(i=0;i<MAX_SIZE;i++)
    {
        list[i]=i; //각 배열의 원소의 값을 번호로 초기화
    }
        printf("binsearch_rec 이용 0~32에서 6찾기 : %d\n",binsearch_rec(list,6,0,32));
        printf("binsearch_itr 이용 0~32에서 6찾기 : %d\n",binsearch_itr(list,6,0,32));
    return 0;
}
int binsearch_itr(int list[], int searchnum, int left, int right)  //반복적으로 짠 이진탐색
{
    int middle; //int형 변수 middle 선언
    printf("*******binsearch_itr 호출*******\n");
    while(left<=right) //left가 right 이하일때 반복
    {middle=(left+right)/2;  //미들은 left와 right의 산술평균
    switch(COMPARE(list[middle],searchnum))  //COMPARE 의 값을 받아와 그에 따라 switch-case로 판단
    {
    case -1 : left=middle+1;  
                break;    //-1경우 left에 middle+1로 대입 후 break
    case 0 :    return middle;
                break//0경우 middle값 리턴 후 break
    case 1 : right=middle-1;
                break//1경우 right에 middle-1로 대입 후 break
    }
    }
    return -1//while 루프가 깨졌을 경우 반환값 -1
}
int binsearch_rec(int list[], int searchnum, int left, int right) //recursive function으로 짠 이진탐색
{
    int middle;//int형 변수 middle 선언
    printf("*******binsearch_rec %d 호출*******\n",i);
    while(left<=right)//left가 right 이하일때 반복 recursive function이라서 if 를 써도 무방하다.
    {middle=(left+right)/2;//미들은 left와 right의 산술평균
    switch(COMPARE(list[middle],searchnum)) //COMPARE 의 값을 받아와 그에 따라 switch-case로 판단
    {
    case -1 :
                return binsearch_rec(list,searchnum,middle+1,right);
                break//-1경우 binsearch_rec함수의 left자리에 middle+1, right 인자에 right 넣어 호출 후 break
    case 0 :
                return middle; 
                break//0의 경우 middle값 리턴 후 break
    case 1 : 
                return binsearch_rec(list,searchnum,left,middle-1);
                break//1경우 binsearch_rec함수의 left자리에 left, right 인자에 middle-1 넣어 호출 후 break
    }
    }
    return -1//while 루프가 깨졌을 경우 반환값 -1
}
cs




*아래쪽 binserach_rec 이용 0~32에서 6찾기 오타입니다. rec를 itr로 바꿔주세요.




2. We can maintain a linear list circularly in an array, circle[MAX_SIZE]. We set up front and rear indices similar to those used for a circular queue.

(a) Obtain a formula in terms of front, rear, and MAX_SIZE for the number of elements in the list.

(b) Write a function that deletes the k-th element in the list.

(c) Write a function that inserts an element, item, immediately after the k-th element.

(d) What is the time complexity of your functions for (b) and (c)?




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 8 // 배열의 기본 최대 크기 상수 8
int multi=1//배열의 크기를 동적 메모리 할당할 때 사용할 전역 변수 multi
int front = 0//원형 선형 리스트의 front 전역 변수
int rear = 0//원형 선형 리스트의 rear 전역 변수
void del_list(int *list); //k번째 원소 삭제 함수
void insert_list(int *list); //k번째 다음 공간에 원소 삽입 함수
void init(int *arr); //배열을 0으로 초기화 하는 함수, 0을 빈 공간으로 사용하였다.
void print(int *arr); // 배열 프린트 함수
void full(int *list); // 배열이 꽉찼을 때 동적 메모리로 배열의 크기를 늘려주는 함수
int menu(); //메뉴 호출 함수
int main(void)
{
    int *arr; //포인터변수 arr, 배열의 크기를 정확히 알 수 없기 때문에 포인터를 배열처럼 사용한다.
    int m; //메뉴 번호로 사용할 변수 m
    arr=(int*)malloc(sizeof(int)*MAX_SIZE); //sizeof(int)*MAX_SIZE 만큼의 크기의 메모리를 지정
    init(arr); // arr을 0으로 이니셜라이징
    while(1//무한루프
    {m=menu(); //m이 -1이면 루프 탈출
    if(m==-1)
        break;
    else if(m==1)  //m이 1이면 배열 출력
        print(arr);
    else if(m==2//m이 2면 원소 삽입 함수 호출
        insert_list(arr);
    else if(m==3//m이 3이면 원소 삭제 함수 호출
        del_list(arr);
    }
    free(arr); //arr의 동적 메모리 free
    return 0;
}
void del_list(int *list)
{
    int i,k;
    printf("인덱스를 입력하세요: ");
    scanf("%d"&k);
    if(front==rear)  //front는 맨 앞 원소의 인덱스 바로 앞을 말한다. rear를 증가하지않고 둘을 검사하면 empty 검사이다.
        printf("리스트가 비어있습니다.\n");
    else if(list[k]==0// 0값을 empty로 사용하였다.
        printf("이미 비어있는 공간입니다.\n");
    else
    {
        for(i=k;i<MAX_SIZE*multi;i++)  //k번째 원소를 삭제할 것이기 때문에  k부터 전체 배열크기 이전까지 반복해준다.
            list[i]=list[i+1]; // 하나 다음 원소를 이전의 공간에 대입해준다. 즉 왼쪽으로 한칸씩 당긴다.
        rear=(rear-1)%(MAX_SIZE*multi); // rear를 하나 감소해준다. 나머지로 하는 이유는 circular이기 때문이다.
    }
    list[MAX_SIZE*multi-1]=0//꽉찼을 때 이함수를 호출하면 마지막에 쓰레기 값이 들어가므로 마지막 원소에 0을 대입해준다.
    print(list); //배열 프린트
}
void insert_list(int *list)
{
    int i,k,item;
    printf("k번째 원소 뒤에 item을 넣습니다. 차례로 입력하세요: ");
    scanf("%d %d",&k,&item);
        rear=((rear)+1) % (MAX_SIZE*multi);  //insert 함수는 rear를 증가시키고 시작한다.
        if(front==rear)   //front와 rear가 같으면 full 함수를 호출한다.
        {    
            full(list);
    for(i=(MAX_SIZE*multi/2);i<MAX_SIZE*multi;i++//full함수때문에 전역변수 multi가 2배가 된 후이기때문에 나머지 2를 해준다.
        list[i]=0;} // 즉 처음에 인덱스가 0~7 이었으나 full이후 0~15가 되었으므로 8~15를 0으로 초기화 시켜준다. 그 이후 역시 같다.
        if(k+1==MAX_SIZE*multi) 
            /*이것은 마지막 배열공간을 k로택한 경우이다. 이경우 원래대로라면 맨 처음의 경우front를 7로 바꾸고 인덱스 0에 원소를 삽입해야한다.
            하지만 이 경우 함수가 너무 복잡해지기 때문에 나는 차라리 이전의 배열 공간에 있었던 원소들을 한칸씩 오른쪽으로 밀고 index 1에 
            원하는 값을 대입하기로 하였다. 이 방법은 k값이 마지막 배열공간일 때만 신경쓰면 되고, front값을 처음에 0으로 설정해 놓았을 경우
            절대로 프로그램이 종료할 때까지 다른 값으로 바뀌지 않기 때문에 매우 직관적이다. 배열이 꽉찰 경우는 이미 앞에서 검사했기 때문에
            문제가 없다.*/
    {
        for(i=multi*(MAX_SIZE)-1;i>0;i--)
        {list[i]=list[i-1];} // 오른쪽으로 한칸씩 원소를 밀었다.
            list[1]=item; //1번 index에 원하는 값 대입
    }
        else if(k>=rear)  //위의 방법으로 원형 선형 리스트를 구현하였기 때문에 k가 rear 이상인 경우는 전부 걸러낼 수 있다.
            {printf("잘못된 입력입니다.\n");
        rear--;} // 그리고 처음에 rear를 증가시키고 시작했기 때문에 다시 빼준다.
        else{
        for(i=multi*(MAX_SIZE)-1;i>k;i--//이것은 일반적인 경우로 k번째 다음에 공간을 만들기 위해 제일 마지막 원소부터 그 이전원소를 하나씩 오른쪽으로 밀어주는 것을
        {list[i]=list[i-1];}              // 반복문으로 나타낸 것이다. 
            list[k+1]=item;                // k+1 index를 기점으로 원소를 하나씩 오른쪽으로 민 후 원하는 자리에 item을 대입해준다.
    }
        print(list);  //배열 프린트
}
void init(int *arr)
{
    int i;
    for(i=0;i<MAX_SIZE*multi;i++)
        arr[i]=0;
}
void print(int *arr)
{
    int i;
    for(i=0;i<MAX_SIZE*multi;i++)
        printf("%3d ",arr[i]);  //예쁘게 하려고 3d로 자리수를 맞춰주었다.
    printf("\n");
    printf("front   :   %d    rear   :   %d\n",front,rear);
}
int menu()
{
    int m;
    printf("=====================\n");
    printf("1. 리스트 출력\n2. 원소 입력(입력한 인덱스 바로 뒤에 삽입)\n3. 원소 삭제(입력한 인덱스의 원소)\n(-1은종료)\n");
    printf("=====================");
    scanf("%d"&m);
    return m;
}
void full(int *list)
{
    multi*=2//전역변수의 크기를 2배씩 늘려준다.
    realloc(list,sizeof(int)*MAX_SIZE*multi); // 따라서 배열이 꽉 찰때마다 크기가 2배씩 계속 증가한다.
    front=0//front를 0으로 만들어준다. 위에서 말했듯이 바뀔 일이 없다.
    rear=((MAX_SIZE*multi)/2); // rear는 하나가 더 채워졌으므로 8,16,32 .. 등이 된다.
}
cs





반응형
반응형

이 게시판은 fundamentals of data structures in C라는 교재를 이용한 자료구조 수업을 들을 때 공부 했던 것들을 올리는 게시판 입니다. 하지만 별다른 설명은 올리지 않고 작성한 코드와 결과만 올려놓았습니다. 상세한 설명이 필요한 경우 댓글로 이메일 적어주시면 보내드리겠습니다. 

반응형
반응형

1. There are three towers and 64 disks of different diameters placed on the first tower. The disks are in order of decreasing diameter as one scans up the tower. Monks were reputedly supposed to move the disk from tower 1 to tower 3 obeying the rules :




(a) Only one disk can be moved at any time.

(b) No disk can be placed on top of a disk with a smaller diameter.

Write a recursive function that prints out the sequence of moves needed to accomplish this task.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*****************************************************************
num : 원판의 갯수 from : 옮기는 판이 원래 있던 기둥
to : 옮기는 판이 옮겨질 기둥  disk : 사용자가 입력한 원판의 개수
pass_stop : from에 있던 (n-1)개의 원판이 to로 가기 위해 경유하는 기둥 
count : 움직인 횟수
기둥은 총 3개가 있는데 각 기둥을 정수 1,2,3으로 표현하였다.
****************************************************************/
 
#include <stdio.h>
void Hanoi(int num, int from, int to);
int count = 0;
int main(void)
{
    int disk = 0
    printf("원판 수를 입력하세요: ");
    scanf("%d"&disk); // 옮길 원판 개수 입력
    Hanoi(disk, 13); // 시작 위치 : 기둥1 도착 위치 : 기둥3
    printf("총 움직인 횟수는 %d회 입니다.\n", count);
    return 0;
}
void Hanoi(int num, int from, int to) 
{
    int pass_stop = 2// 각 기둥을 1,2,3 이라고 정함, 1+2+3=6
    if (num <= 1)
    {
        printf("%d번째 원판을 %d에서 %d로 옮겼습니다.\n", num, from, to);
        count++;
    }
    else {
        pass_stop = 6 - from - to;
        Hanoi(num - 1, from, pass_stop); // (n-1)개를 from에서 pass_stop으로 옮긴다.
        printf("%d번째 원판을 %d에서 %d로 옮겼습니다.\n", num, from, to);
        count++;
        Hanoi(num - 1, pass_stop, to); // (n-1)개를 pass_stop에서 to 로 옮긴다.
    }
}
cs






2. Write the iterative(반복의) (Program 2-1) and recursive(회귀의) (Program 2-2) binary search function and measure the worst case performance of both functions (using Program 1.25), and analyze average case time complexity of binary search algorithm.


*프로그램 1.25에 써있는 numtime 대로 하면 cpu 성능이 너무 좋아 시간이 제대로 나오지 않으므로 곱하기 100씩 한 수를 넣어주었다.





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define COMPARE(mid,searchnum)  (((mid)<(searchnum)) ? (-1) : (((mid)>(searchnum)) ? (1) : (0)))  //미들값과 찾는값의 크기를 비교하여 해당 값 반환
/* mid<searchnum 이면 -1 반환, mid>searchnum이면 1 반환, mid=searchnum이면 1 반환*/
#define MAX_SIZE 1001 //상수 MAX_SIZE는 1001
#define ITERATIONS 16 //상수 ITERATIONS는 16
int binsearch_rec(int list[], int searchnum, int left, int right);
int binsearch_itr(int list[], int searchnum, int left, int right);
int main(void)
{
    int i,j,position;  //int형 변수 i,j,positon 선언
    int list[MAX_SIZE]; //int형 배열 list 선언, 배열의 크기는 MAX_SIZE=1001
    int sizelist[]={0,10,20,30,40,50,60,70,80,90,100,200,400,600,800,1000}; //이진탐색을 시행할 크기
    int numtimes[]={3000000,1200000,600000,500000,400000,400000,400000,300000,300000,200000,200000,100000,50000,50000,50000,20000}; // 이진탐색을 돌릴 횟수
    clock_t start, stop; //clock_t는 time.h에서 정의되어있는데 long 형과 같다. start, stop 변수 선언
    double duration, total; //double 형 변수 duration, total 선언
    for(i=0;i<MAX_SIZE;i++)
    {
        list[i]=i; //각 배열의 원소의 값을 번호로 초기화
    }
        printf("=====================ITERATIVE=====================\n");
        printf("sizelist[i]  numtimes[i]  stop-start     total     duration     positon\n");
    for(i=0;i<ITERATIONS;i++
    {
        start=clock(); //start에 프로그램이 시작될 때부터 지난 틱수 저장
        for(j=0;j<numtimes[i];j++// j=0부터 numtimes[i] 미만까지 반복
        {
            position=binsearch_itr(list,sizelist[i]+1,0,sizelist[i]); //positon에 binseasrch_itr함수의 반환값 저장 최악의 경우로 없는 숫자를 찾는다.
                                                                    //예를들어 sizelist[2]면 searchnum은 0에서 10사이에서 11을 찾는 것이다. 리턴은 -1일 것이다.
        }
        stop=clock(); //stop에 프로그램이 시작될 때부터 지난 틱수 저장
        total=((double)(stop-start))/CLOCKS_PER_SEC; //CLOCKS_PER_SEC는 초당 클락수이다.1000으로 정의되어 있다. stop-start=사이의 클락수이므로 연산을 하면 시간(초)가 반환된다.
        duration=(total/numtimes[i]); //total을 numtimes[i]로 나눈 값
        printf("%11d %11d %11d %11f %11f %11d\n",sizelist[i],numtimes[i],(int)(stop-start),total,duration,position); //화면에 각각의 값을 11자리씩 출력
        list[sizelist[i]]=sizelist[i]; //reset value 라고 써있는데 왜 있는지 잘 모르겠다.
    }
    printf("=====================RECURSIVE=====================\n");
    printf("sizelist[i]  numtimes[i]  stop-start     total     duration     positon\n");
    for(i=0;i<ITERATIONS;i++)
    {
        start=clock();    //start에 프로그램이 시작될 때부터 지난 틱수 저장
        for(j=0;j<numtimes[i];j++)// j=0부터 numtimes[i] 미만까지 반복
        {
            position=binsearch_rec(list,sizelist[i]+1,0,sizelist[i]); //positon에 binseasrch_rec함수의 반환값 저장 최악의 경우로 없는 숫자를 찾는다.
                                                                    //예를들어 sizelist[2]면 searchnum은 0에서 10사이에서 11을 찾는 것이다. 리턴은 -1일 것이다.
        }
        stop=clock(); //stop에 프로그램이 시작될 때부터 지난 틱수 저장
        total=((double)(stop-start))/CLOCKS_PER_SEC; //CLOCKS_PER_SEC는 초당 클락수이다.1000으로 정의되어 있다. stop-start=사이의 클락수이므로 연산을 하면 시간(초)가 반환된다.
        duration=(total/numtimes[i]); //total을 numtimes[i]로 나눈 값
        printf("%11d %11d %11d %11f %11f %11d\n",sizelist[i],numtimes[i],(int)(stop-start),total,duration,position); //화면에 각각의 값을 11자리씩 출력
        list[sizelist[i]]=sizelist[i]; //reset value 라고 써있는데 왜 있는지 잘 모르겠다.
    }
    return 0;
}
int binsearch_itr(int list[], int searchnum, int left, int right)  //반복적으로 짠 이진탐색
{
    int middle; //int형 변수 middle 선언
    while(left<=right) //left가 right 이하일때 반복
    {middle=(left+right)/2;  //미들은 left와 right의 산술평균
    switch(COMPARE(list[middle],searchnum))  //COMPARE 의 값을 받아와 그에 따라 switch-case로 판단
    {
    case -1 : left=middle+1;  
                break;    //-1경우 left에 middle+1로 대입 후 break
    case 0 :    return middle;
                break//0경우 middle값 리턴 후 break
    case 1 : right=middle-1;
                break//1경우 right에 middle-1로 대입 후 break
    }
    }
    return -1//while 루프가 깨졌을 경우 반환값 -1
}
int binsearch_rec(int list[], int searchnum, int left, int right) //recursive function으로 짠 이진탐색
{
    int middle;//int형 변수 middle 선언
    while(left<=right)//left가 right 이하일때 반복 recursive function이라서 if 를 써도 무방하다.
    {middle=(left+right)/2;//미들은 left와 right의 산술평균
    switch(COMPARE(list[middle],searchnum)) //COMPARE 의 값을 받아와 그에 따라 switch-case로 판단
    {
    case -1 : return binsearch_rec(list,searchnum,middle+1,right);
                break//-1경우 binsearch_rec함수의 left자리에 middle+1, right 인자에 right 넣어 호출 후 break
    case 0 :    return middle; 
                break//0의 경우 middle값 리턴 후 break
    case 1 : return binsearch_rec(list,searchnum,left,middle-1);
                break//1경우 binsearch_rec함수의 left자리에 left, right 인자에 middle-1 넣어 호출 후 break
    }
    }
    return -1//while 루프가 깨졌을 경우 반환값 -1
}
 
 
cs


반응형

'컴퓨터 & 프로그래밍 & 전자공학 > Data Sturcture' 카테고리의 다른 글

dfs, bfs, prim, kruskal  (0) 2017.10.01
preorder, postorder, inorder, heap, tree  (0) 2017.10.01
stack, queue  (0) 2017.10.01
참고 사항  (0) 2017.10.01
Array, Pointer  (0) 2017.10.01
반응형

1. Array : Let’s assume that we have the following declaration:

1.1. Please store the above data using scanf() function in two 2-dimension array, respectively. You can show the result.

 

1.2. Please create a new array ‘element[2][3]’ to obtain the sum of the value of First array and Second array. For example,

element[1][2] = First[1][2]+Second[1][2].

element[2][1] = First[2][1]+Second[2][1].




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*
    {{16,18,23},{54,91,11}}          {{24,52,77},{16,19,59}}
    1-1)Please store the above data using  function in two  2-dimension array, respectively. You can show the result.
    1-2)Please create a new array ‘Element[2][3]’ to obtain the sum of the value of First array and Second array. For example,
        Element[1][2] = First[1][2]+Second[1][2]. 
        Element[2][1] = First[2][1]+Second[2][1].
    ROW : 행 수 COL : 열 수
    array_input : 배열에 원소 값을 사용자가 입력할 수 있게 하는 함수
    array_print : 배열을 원소별로 출력해주는 함수
    array_sum   : 배열의 합을 구해주는 함수
    First[ROW][COL] : 2*3 사이즈의 2차원 배열1
    Second[ROW][COL] : 2*3 사이즈의 2차원 배열2
    Element[ROW][COL] : 2*3 사이즈의 2차원 배열, 동일한 위치의 First와 Second 의 원소의 합이 들어갈 배열
*/
#include <stdio.h>
#define ROW 2
#define COL 3
void array_input(int num,int array[][COL]);
void array_print(int num,int array[][COL]);
void array_sum(int array1[][COL],int array2[][COL],int array3[][COL]);
int main(void)
{
    int First[ROW][COL];
    int Second[ROW][COL];
    int Element[ROW][COL];
    array_input(1,First);
    array_input(2,Second);
    array_sum(First,Second,Element);
    printf("\n");
    array_print(1,First);
    printf("\n");
    array_print(2,Second);
    printf("\n");
    array_print(3,Element);
    return 0;
}
void array_input(int num,int array[][COL])
{
    int i;int j;
    printf("<%d번째 배열 입력>\n",num);
    for(i=0;i<ROW;i++)
    {
        for(j=0;j<COL;j++)
        {
        printf("%d번배열[%d][%d] 값 입력 : ",num,i,j);
        scanf("%d",&array[i][j]);
        }
    }
}
void array_print(int num,int array[][COL])
{
    int i;int j;
    for(i=0;i<ROW;i++)
    {
        for(j=0;j<COL;j++)
        {
        printf("%d번배열[%d][%d] : %d\n",num,i,j,array[i][j]);
        }
    }
}
void array_sum(int array1[][COL],int array2[][COL],int array3[][COL])
{
    int i;int j;
    for(i=0;i<ROW;i++)
    {
        for(j=0;j<COL;j++)
        {
        array3[i][j]=array1[i][j]+array2[i][j];
        }
    }
}
cs

 

 


2. Pointer : Let’s assume the next arrangement was declared. Calculate the final value of the following expression:

2.1. *(**p+3), *(**p+1), p[0], **(p[1]+1), *(p[1] +1)

2.2. *text, *(text+3), *(text+7)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
int main(void)
{
    char *p[3][2]={"abcd","efgh","ijklm","nop","qrstuv","wxyz"};
    char *text;
    char more[]="Happy Holidays";
    text=&more[4]; //'y'의 주소
    printf("*(**p+3)=%c\n",*(**p+3));
    printf("*(**p+1)=%c\n",*(**p+1));
    printf("p[0]=%x\n",p[0]);
    printf("**(p[1]+1)=%c\n",**(p[1]+1));
    printf("*(p[1]+1)=%x\n",*(p[1]+1));
    printf("\n");
    printf("*text=%c\n",*text);
    printf("*(text+3)=%c\n",*(text+3));
    printf("*(text+7)=%c\n",*(text+7));
}
cs







반응형
반응형

앞장에서 간단한 정수 계산기를 만들어본 적이 있다. 이 계산기 프로그램에 메뉴를 추가하도록 한다. 다음과 같은 메뉴를 화면에 출력하고 사용자가 메뉴 중에서 하나를 선택할 때 까지 반복을 계속한다. do...while 반복문을 사용하여 사용자가 적절한 선택을 했는지를 검사하도록 하라. 만약 사용자가 A, S, M, D, Q가 아닌 다른 문자를 입력하면 "연산을 선택하시오:" 메시지를 계속해서 출력한다. 하나의 메뉴가 선택되면 해당되는 연산을 실행하고 다시 메뉴를 선택할 수 있도록 하라. 반복을 종료하는 메뉴인 Q는 break 문을 이용하여 구현하도록 하라.

1)정수계산기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
int main(void)
{
char a;
int x,y;
printf("****************\n");
printf("A----Add\n");
printf("S----Subtract\n");
printf("M----Multiply\n");
printf("D----Divide\n");
printf("Q----Quit\n");
printf("****************\n");
do{
printf("연산을 선택하시오:");
scanf(" %c"&a);
if(a=='Q')
    break;
if((a=='A')||(a=='S')||(a=='M')||(a=='D'))
{
    printf("두 수를 공백으로 분리하여 입력하세요: ");
scanf("%d %d"&x, &y);
if(a=='A')
    printf("연산의 결과는 %d입니다.\n", x+y);
else if(a=='S')
    printf("연산의 결과는 %d입니다.\n", x-y);
else if(a=='M')
    printf("연산의 결과는 %d입니다.\n", x*y);
else if(a=='D')
    printf("연산의 결과는 %d입니다.\n", x/y);
break;
}
}while(1);
return 0;
}
cs




2)실수계산기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
int main(void)
{
char a;
double x,y;
printf("****************\n");
printf("A----Add\n");
printf("S----Subtract\n");
printf("M----Multiply\n");
printf("D----Divide\n");
printf("Q----Quit\n");
printf("****************\n");
do{
printf("연산을 선택하시오:");
scanf(" %c"&a);
if(a=='Q')
    break;
if((a=='A')||(a=='S')||(a=='M')||(a=='D'))
{
    printf("두 수를 공백으로 분리하여 입력하세요: ");
scanf("%lf %lf"&x, &y);
if(a=='A')
    printf("연산의 결과는 %lf입니다.\n", x+y);
else if(a=='S')
    printf("연산의 결과는 %lf입니다.\n", x-y);
else if(a=='M')
    printf("연산의 결과는 %lf입니다.\n", x*y);
else if(a=='D')
    printf("연산의 결과는 %lf입니다.\n", x/y);
break;
}
}while(1);
return 0;
}
cs


반응형
반응형

중첩 반복문을 사용하여서 다음과 같이 출력하는 프로그램을 작성하여 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int main(void)
{
    int a, b, c;
printf("정수를 입력하세요");
scanf("%d"&a);
for(b=1;b<=a;b++)
{
    for(c=1;c<=b;c++)
    {
    printf("%d ", c);
    }
printf("\n");
}
return 0;
}
cs




반응형

+ Recent posts