반응형

인하대학교 전자공학과 데이터 구조 포인터, 어레이 과제 (pointer, array)


인하대학교 전자공학과 데이터 구조 하노이의 탑, 이진 탐색(binary search, tir, recursive)


인하대학교 전자공학과 데이터 구조 시스템 스택, 선형 리스트 (system stack, linear list)


인하대학교 전자공학과 데이터 구조 preorder, postorder, max heap


인하대학교 전자공학과 데이터 구조 dfs, bfs, 프림, 크루스칼 (prim, kruskal)


소스코드, 수도코드, 플로우차트(순서도), 분석 및 고찰, 결과창 등이 들어있는 보고서입니다.


전부 만점받은 보고서입니다. 

반응형
반응형

1. Implement the dfs and bfs algorithms using the given graph and adjacency lists (Figure 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
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
#include <stdio.h>
#include <stdlib.h>
#define SIZE 8
#define FALSE 0  //boolean 연산을 위한 상수 설정
#define TRUE 1   //boolean 연산을 위한 상수 설정
typedef struct node *pn; //node형 포인터 자료형 pn
typedef struct node{
    int vertice;
    pn link;
}node; //node 자료형 안에는 node의 주소를 나타내는 link와 정수형 변수 vertice 포함
void add(pn a);
void dfs(int v);
void bfs(int v);
void addq(int *rear,int value);
int deleteq(int *front);
 
pn graph[SIZE]; //pn형 크기 8짜리 배열 graph
int visited[SIZE]; //int형 크기 8짜리 배열 visited, 방문한 노드 삽입
int queue[SIZE]; // 사이즈 8짜리 큐
 
int main(void)
{
pn cup; //pn형 변수 cup (포인터) 임시 저장소
int i;
for(i=0;i<SIZE;i++//graph 배열의 원소 초기화
{
    graph[i]=0;
}
add(&graph[0],1);    add(&graph[0],2);
add(&graph[1],0);    add(&graph[1],3);    add(&graph[1],4);
add(&graph[2],0);    add(&graph[2],5);    add(&graph[2],6);
add(&graph[3],1);    add(&graph[3],7);
add(&graph[4],1);    add(&graph[4],7);
add(&graph[5],2);    add(&graph[5],7);
add(&graph[6],2);    add(&graph[6],7);
add(&graph[7],3);    add(&graph[7],4);    add(&graph[7],5);    add(&graph[7],6); 
//주어진 그림대로 그래프 초기화 하는 과정
for(i=0;i<SIZE;i++){
cup=graph[i]; //graph[i]를 cup에 대입
printf("graph[%d]    ",i);
while(cup){ //cup이 0이 아니면(각 노드는 링크드 리스트로 구성되어 있어 마지막 노드는 0을 가리킴)
printf("%d ",cup->vertice); //cup->vertice 출력
cup=cup->link; //cup에 cup->link 대입
}
printf("\n"); //개행문자 출력
}
printf("DFS : ");dfs(0); printf("\n"); //dfs 실행
for(i=0;i<SIZE;i++)
{visited[i]=FALSE;} //visited된 노드들 초기화 (bfs 를 하려면 초기화 시켜줘야함)
printf("BFS : ");bfs(0); printf("\n"); //bfs 실행
return 0;
}
 
void add(pn *a,int value){  //그래프의 노드를 연결해주는 함수
    /*a에 해당하는 것이 노드를 가리키는 포인터, value는 추가할 값이다.
    a에 이미 연결되어 있는 메모리가 존재하면 계속 링크를 타고 가다가 링크가 0인
    메모리에 동적메모리할당 한것을 링크시켜 그곳에 value를 넣어준다
    add(&graph[0],1);    add(&graph[0],2); 예를들어 main함수에서 나온 것인데
    맨처음 graph[0]이 1을 갖는 메모리를 가리키고 1를 갖는 메모리가 2를 갖는 메모리를 가리키고
    2를 갖는 메모리의 링크는 0이다. 이런식으로 진행이 된다. 링크가 0인지 아닌지는 함수가 스스로 판단한다.*/
    pn *check=0//check를 NUL로 초기화,check는 이중포인터
    pn tmp = (pn)malloc(sizeof(node)); //tmp가 가리키는 곳에 node size 동적 메모리 할당
    check=a; //check가 가리키는 주소 = a가 가리키는 주소
    while(1){
        if((*check)==0){break;} // check가 가리키는 주소가 0이면 루프 탈출
    else if(((*check)->link)!=0){ //(*check)->link)!=0)이면 
        check=&((*check)->link); //check에 &((*check)->link) 대입
    }
    else//이외의경우
        check=&((*check)->link);  //check에 &((*check)->link) 대입하고 break
        break;}}
    *check=tmp; //check가 가리키는 주소에 tmp 대입
    (*check)->vertice=value; //value를 마지막 노드의 vertice 에 삽입
    (*check)->link=0//마지막 노드의 링크는 0
}
void dfs(int v){
    pn w; //pn형 변수 w (포인터)
    visited[v]=TRUE; //visited[v]에 1 대입
    printf("%5d",v); //5자리수로 해서 출력
    for(w=graph[v];w;w=w->link) //초기식 : w=graph[v], 조건식 : w가 존재하면(not 0) 증가식 : w에 w->link 대입
    {
        if(!visited[w->vertice]) //w가 가리키는 주소의 vertice가 방문하지 않은 노드라면
            dfs(w->vertice); //dfs 순환 호출
    }
}
void bfs(int v){
    pn w; //pn형 변수 w(포인터)
    int front=-1//front와 rear 를 -1로 설정(원형 큐)
    int rear=-1;
    printf("%5d", v); // 5의 전체 크기로 출력
    visited[v]=TRUE; //visited[v]에 true 대입(1)
    addq(&rear,v); //v를 원형 큐에 삽입
    while(front!=rear){ //front가 not rear 이면
    v=deleteq(&front); // 맨 앞 원소 delete
    for(w=graph[v];w;w=w->link){ //초기식 : w=graph[v], 조건식 : w가 존재하면(not 0) 증가식 : w에 w->link 대입
        if(!visited[w->vertice]) //w가 가리키는 주소의 vertice가 방문하지 않은 노드라면
        {
        printf("%5d", w->vertice); //w->vertice 출력
        addq(&rear,w->vertice); //w->vertice 큐에 삽입
        visited[w->vertice]=TRUE;  //visited[w->vertice]에 true 대입(1)
        }}}}
void addq(int *rear,int value){ //원형 큐에서 삽입
    *rear=(*rear)%SIZE;
    queue[++(*rear)]=value;
}
int deleteq(int *front){ //원형 큐에서 원소 삭제
    return queue[++(*front)%SIZE];
}
 
cs



2. Refine Prim’s algorithm, Kruskal’s algorithm into a C function that finds a minimum cost spanning tree.



Prim’s algorithm


Kruskal’s algorithm


graph


<Prim's 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
#include <stdio.h>
#include <stdlib.h>
 
typedef struct edge{ //edge 형 변수
    int left;  //int형변수 left,right,weight,u를 포함한다.
    int right;
    int weight;    
    int u;  // 어떤 집합에 속할지 정해준다. (여기서는 사용하지 않음)
}edge; 
 
void Prim(edge E[],edge T[]);
 
int Ecount=0;    //몇번째 E의 원소를 참조하고 있는가
int TVlength=1;  //노드가 들어갈 집합
int Tlength=0;   //dege T의 길이
int TV[7]={0,-1,-1,-1,-1,-1,-1}; //노드가 들어갈 집합, 몇번부터 시작하는지는 상관 없으나 0번부터 시작하라고 해서 0번만 넣고 나머지는 나올 수 없는 -1로 초기화
edge T[6];     //우리가 prim algorithm 에 의해 선택한 간선을 넣을 집합
edge E[9];    //기존에 주어진 set
 
int main(void)
{
    int i;    
    for(i=0;i<20;i++){
    T[i].left=-1;    T[i].right=-1;    T[i].u=-1;    T[i].weight=-1;}
    E[0].left=5;    E[0].right=0;    E[0].weight=10;    E[0].u=-1;
    E[1].left=0;    E[1].right=1;    E[1].weight=28;    E[1].u=-1;
    E[2].left=1;    E[2].right=2;    E[2].weight=16;    E[2].u=-1;
    E[3].left=2;    E[3].right=3;    E[3].weight=12;    E[3].u=-1;
    E[4].left=6;    E[4].right=3;    E[4].weight=18;    E[4].u=-1;
    E[5].left=4;    E[5].right=3;    E[5].weight=22;    E[5].u=-1;
    E[6].left=4;    E[6].right=6;    E[6].weight=24;    E[6].u=-1;
    E[7].left=5;    E[7].right=4;    E[7].weight=25;    E[7].u=-1;
    E[8].left=6;    E[8].right=1;    E[8].weight=14;    E[8].u=-1//책에 나와있는대로 초기화
    Prim(E,TV); //Prim 알고리즘 실행
    for(i=0;i<6;i++)
    {printf("%d %d %d %d\n",T[i].left,T[i].right,T[i].u,T[i].weight);} //확인을 위해 출력
    return 0;
}
void Prim(edge E[],int TV[]){
    int i=0int j; int k;int count=0int flag=0
    int tmpisl=-1; edge tmpedge;
    while(Tlength<6){
        /*for(u=0;u<TVlength;u++)
        {printf("%d",TV[u]);}
        printf("\n");*/
        tmpisl=-1;  tmpedge.left=-1; tmpedge.right=-1; tmpedge.u=-1; tmpedge.weight=100//tmp 각 원소 초기화 weight는 무조건 모든 간선 weight보다 크게
            for(j=0;j<9;j++){ //j는 0부터 9보다 작을 때까지
                count=0;  //count=0으로 초기화
                for(k=0;k<TVlength;k++)  //k=0부터 TVlength 보다 작을 때까지
                {if((TV[k]==E[j].left)) //TV[k]가  E[j].left와 같으면
                count++;} //count ++;
                for(k=0;k<TVlength;k++){ //k=0부터 TVlength 보다 작을 때까지
                if((TV[k]==E[j].right)) //TV[k]가  E[j].right와 같으면
                count++;} //count ++;
                printf("i=%d j=%d k=%d count=%d TLength=%d TVLength=%d\n",i,j,k,count,Tlength,TVlength);
                if(count==1){ //즉 E[j](간선)에 노드 TV[k]가 들어있으면 만약 count==2면 cycle 이라서 안됨
                    if(E[j].weight<tmpedge.weight) //E[j].weight<tmpedge.weight 면(작은걸 택해야 하니까)
                    {
                    tmpedge.left=E[j].left;
                    tmpedge.right=E[j].right;
                    tmpedge.u=E[j].u;
                    tmpedge.weight=E[j].weight; //tmp에 E[j]의 요소 대입
                    flag=0//flag에 0 대입
                    for(k=0;k<TVlength;k++){ //k=0부터 TVlength 아래까지
                        if(E[j].left==TV[k]) //E[j].left==TV[k]면 루프탈출
                            break;
                        else flag++//아니면 flag++
                    }
                    if(flag==TVlength) //flag가 TVlength면
                        tmpisl=E[j].left; //tmpisl 에 E[j].left대입
                    flag=0//flag 0으로 초기화
                    for(k=0;k<TVlength;k++){ //k=0부터 k<TVlength 까지
                        if(E[j].right==TV[k])  //E[j].right==TV[k]면 루프탈출
                            break;
                        else flag++;  //아니면 flag++
                    }
                    if(flag==TVlength) //flag==TVlength면
                        tmpisl=E[j].right; // tmpisl에 E[j].right대입;
                    /*TV에 없는걸 tempisl에넣어야함*/}
                }
            }
        TV[TVlength]=tmpisl; //TV에 tmpisl 대입
        TVlength++;  //TVlength 증가
        T[Tlength].left=tmpedge.left;
        T[Tlength].right=tmpedge.right;
        T[Tlength].u=tmpedge.u;
        T[Tlength].weight=tmpedge.weight; //tmp에있는 요소 T[Tlength]에 대입
        Tlength++//Tlength 증가
        i++//i증가
    }
        
}
cs




<Kruskal's 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <stdio.h>
#include <stdlib.h>
 
typedef struct edge{ //edge 형 변수
    int left;  //int형변수 left,right,weight,u를 포함한다.
    int right;
    int weight;    
    int u; // 어떤 집합에 속할지 정해준다.
}edge;
 
void Kruskal(edge E[],edge T[]);
void select_sort(edge vector[],int size);
int notcycle(edge *e,edge T[]);
int makeuni(edge *e,edge T[]);
void jointuni(edge T[]);
 
int uni=0;   //전역변수, 집합의 이름(번호)를 정함
int Ecount=0//E의 인덱스
int Tlength=0//T의 길이(T에 원소 몇개인지)
edge T[6];    //edge형 배열 T 크기 6
edge E[9];    //edge형 배열 E 크기 9
int k;
 
int main(void)
{
    int i;    
    for(i=0;i<20;i++){
    T[i].left=-1;    T[i].right=-1;    T[i].u=-1;    T[i].weight=-1;} //T 초기화 (안나올 값으로)
    E[0].left=5;    E[0].right=0;    E[0].weight=10;    E[0].u=-1;
    E[1].left=0;    E[1].right=1;    E[1].weight=28;    E[1].u=-1;
    E[2].left=1;    E[2].right=2;    E[2].weight=16;    E[2].u=-1;
    E[3].left=2;    E[3].right=3;    E[3].weight=12;    E[3].u=-1;
    E[4].left=6;    E[4].right=3;    E[4].weight=18;    E[4].u=-1;
    E[5].left=4;    E[5].right=3;    E[5].weight=22;    E[5].u=-1;
    E[6].left=4;    E[6].right=6;    E[6].weight=24;    E[6].u=-1;
    E[7].left=5;    E[7].right=4;    E[7].weight=25;    E[7].u=-1;
    E[8].left=6;    E[8].right=1;    E[8].weight=14;    E[8].u=-1;  //교과서에 나온 것처럼 초기화
    Kruskal(E,T); //Kruscal 알고리즘 실행
    for(i=0;i<6;i++)
    {printf("%d %d %d %d\n",T[i].left,T[i].right,T[i].u,T[i].weight);} //출력으로 제대로 나왔나 확인
    return 0;
}
void Kruskal(edge E[],edge T[]){
edge temp;
select_sort(E,9); //E를 가중치의 크기대로 오름차순 정렬한다.
while((Tlength<6)&&(Ecount<9)){ //Tlength가 6보다 작고 Ecount가 9보다 작으면 루프 반복
temp.left=E[Ecount].left;temp.right=E[Ecount].right;temp.weight=E[Ecount].weight;    temp.u=E[Ecount].u; //temp의 각 요소에 E[Ecount]의 요소 대입
E[Ecount].left=-1;E[Ecount].right=-1;E[Ecount].weight=-1//E의 Ecount 원소는 삭제 (-1대입)
makeuni(&temp,T); //temp의 집합을 만들어준다.
jointuni(T); //같은 집합인데 번호가 다른 집합이 있으면 합해준다. temp를 제외한 T만 해준다. (cycle 검사때문에)
for(k=0;k<Tlength;k++){
    printf("T[%d].u=%d ",k,T[k].u);
}
printf("tmp.u : %d\n",temp.u); //T의 원소의 집합 번호와 temp의 집합 번호 확인
if(notcycle(&temp,T)) //싸이클이 생기지 않으면
{
T[Tlength].left=temp.left;T[Tlength].right=temp.right;T[Tlength].weight=temp.weight;    T[Tlength].u=temp.u; //T[Tlength]의 요소에 temp의 요소 대입
Tlength++;Ecount++//Tlength와 Ecount 하나씩 증가
}
else{Ecount++;} //싸이클이 생겼으면 Ecount만 증가
}}
 
void select_sort(edge vector[],int size){ //선택정렬 알고리즘 
    int i; int j; int temp; int index;
    for(i=0;i<size;i++)
    {
        index=i;
        for(j=i+1;j<size;j++)
        {
            if((vector[j].weight)<vector[index].weight){
            index=j;}
        }
        temp=vector[index].weight;
        vector[index].weight=vector[i].weight;
        vector[i].weight=temp;
        temp=vector[index].left;
        vector[index].left=vector[i].left;
        vector[i].left=temp;
        temp=vector[index].right;
        vector[index].right=vector[i].right;
        vector[i].right=temp;
    }
}
int notcycle(edge *e,edge T[]){ //간선이 cycle 형성 하는지 리턴값이 판별 1이면 notcycle, 0이면 cycle
    int check=0;
    int i;
    if(Tlength==0)  //Tlength가 0이면 1반환 
        return 1;
    for(i=0;i<Tlength;i++){ //i=0부터 Tlength 이전까지 반복
        if(e->u==T[i].u){ //e->u 와 T[i].u 가같으면 (집합이 같으면)
            if((e->left==T[i].left)||(e->left==T[i].right)||(e->right==T[i].left)||(e->right==T[i].right)){ //e의 left가 t의 left나 right와 같거나, e의 right가 t의 left나 right와 같거나
            check++;
            printf("Tlength=%d i=%d check=%d\n\n",Tlength,i,check);} //check 증가식
            if(check==2//즉 같은 집합 내에서 
            {return 0;}
        }}
    return 1;
}
int makeuni(edge *e,edge T[]){ //집합을 만드는 함수
    int i; int check=0;
    if(Tlength==0//Tlength가 0이면
    {e->u=uni++return e->u;} //e->u에 uni 대입하고 증가, e->u 리턴
    else{
        for(i=0;i<Tlength;i++)
        {
        if((e->left==T[i].left)||(e->left==T[i].right)||(e->right==T[i].left)||(e->right==T[i].right)) //e의 left가 t의 left나 right와 같거나, e의 right가 t의 left나 right와 같거나
        {check=1;    //check에 1 대입
        e->u=T[i].u; return e->u; //e->u 에 T[i].u 대입 (즉 둘은 같은 집합이됨) e->u 리턴
        break;}
        }
        if(check==0){ //check가 0이면
        e->u=uni++return e->u; //e->u에 uni대입하고 uni 증가시킴, e->u 리턴 (새로운집합)
        }}}
void jointuni(edge T[]){ //집합을 합치는 함수
    int i;
    for(i=0;i<Tlength;i++){ //i=0부터 Tlength 보다 작을때까지 반복
        if((T[i+1].left==T[i].left)||(T[i+1].left==T[i].right)||(T[i+1].right==T[i].left)||(T[i+1].right==T[i].right)){ //T[i+1]의 left가 T[i]의 left나 right와 같거나, T[i+1]의 right가 T[i]의 left나 right와 같거나,
            if(T[i+1].u<T[i].u)   //T[i+1].u가 T[i].u보다 작으면
                T[i].u=T[i+1].u; //T[i+1].u를 T[i].u에 대입
            else
                T[i+1].u=T[i].u; //작은 쪽으로 집합 번호를 매긴다.
        }}}
cs





반응형
반응형

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







반응형

+ Recent posts