project #3   다항식 연산                  자료구조                     조장:             20113311 장동규                     조원:        ...
순서         •조원별 업무분담               •일정 계획                    -회의록               •문제 파악-Linked List라는 자료구조를 활용하여           ...
1) 조원별 업무 분담이름            역할장동규           조장, 보고서 작성, 자료 조사정예린           코딩, 자료 조사정민정           알고리즘, 자료조사서영진           보고...
3)문제파악링크드 리스트(Linked List)배열 구조의 단점을 보안한 자료구조이다. 배열은 인덱스를 이용하여 해당 주소에 바로 접근할 수 있는 장점이 있지만, 단점으로는 삽입, 삭제 연산이 복잡하다. 그리고 배열은 ...
다음은 링크드 리스트를 구현한 소스이다.#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct tagNode{         char Name[20...
{                *Head = Node;         }         else         {      NODE* Current = *Head;                while(Current -...
while(Current != NULL && 0 < index)        {                index--;                Current = Current -> NextNode;        ...
{               ConnectNode -> NextNode = (*Head);               *Head = ConnectNode;        }        else        {       ...
{                Remove = Remove -> NextNode;        }        if(*Head == Remove)        {                *Head = Remove -...
struct 구조체 이름                           {                        자료형 자료이름;                        자료형 자료이름;               ...
즉, DATA-       DATA-지                      LINK 계수부분        수부분과 같이 한 노드가 만들어지게 된다.3) 이러한 노드를 다항식에서 항의 개수만큼 LINK를 이용해 다음 항...
5)소스 구현①소스 분석#include <stdio.h>#include <stdlib.h>typedef struct polynomial{         int degree; //차수         double coef;...
polynomial *temp=(polynomial *)malloc(sizeof(node));//연길리스트의 메모리할당을temp의 포인터 옮기는 정도에 따라 할당해줌        if(temp==NULL)        ...
}                 else                 {                          printf("%dx^%d",p->coef,p->degree); //계수가나 지수가 0이 아니면 계수...
insert_node(plist3,a->coef,a->degree);//차수를   가리키고   있을때,다항식3번째=1+2의 결과값을 저장.                          a=a->link;         ...
break;             }             insert_node(&list1, a, b);    }    printf("다항식1 : ");    print(&list1); //다항식1 출력    prin...
7)최종소스#include <stdio.h>#include <stdlib.h>// 연결리스트 노드의 구조typedef struct listnode{         double coef;         int expon;...
n->link=NULL;         if(plist->tail==NULL)         {                   plist->head=plist->tail=n;         }         else ...
b=b->link;                  }         }                  return 0;}//출력 하기 위한 함수int poly_print(listheader *plist){        ...
{    listheader list1, list2, list3;   //리스트 변수 선언    // 연결 리스트이 초기화    reset(&list1);    reset(&list2);    reset(&list3);...
•실행 화면8)시간복잡도/공간복잡도
Upcoming SlideShare
Loading in …5
×

2012 Ds 03

562 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
562
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

2012 Ds 03

  1. 1. project #3 다항식 연산 자료구조 조장: 20113311 장동규 조원: 20113309 이태구 20113318 정예린 20113315 정민정 20083657 서영진
  2. 2. 순서 •조원별 업무분담 •일정 계획 -회의록 •문제 파악-Linked List라는 자료구조를 활용하여 다항식 연산 •알고리즘 계획 •소스구현•문제점 파악 / 해결법 토의 •최종소스 •시간 복잡도/공간 복잡도
  3. 3. 1) 조원별 업무 분담이름 역할장동규 조장, 보고서 작성, 자료 조사정예린 코딩, 자료 조사정민정 알고리즘, 자료조사서영진 보고서 작성, 자료 조사2)일정계획날짜 계획 링크드 리스트, 다항식 연산에 대해 조사04.12~04.17 해오기, 보고서 작성 링크드 리스트 소스 구현하는 알고리즘, 이04.17~04.19 것을 어떻게 다항식 연산에 활용할 것인지 생각 해오기, 보고서 작성04.19~04.24 알고리즘을 소스로 구현, 최종 보고서 작성
  4. 4. 3)문제파악링크드 리스트(Linked List)배열 구조의 단점을 보안한 자료구조이다. 배열은 인덱스를 이용하여 해당 주소에 바로 접근할 수 있는 장점이 있지만, 단점으로는 삽입, 삭제 연산이 복잡하다. 그리고 배열은 선언시 크기를 미리 정해줘야 하기 때문에 배열 공간 100개를 선언해 놓고 10개만 쓰는 경우(메모리 낭비), 200개가 필요한 경우(공간 부족) 라면 배열 선언 부분을 다시 수정해줘야 하는 불편함이 있다.이러한 단점을 보안해 필요할 때 마다 공간을 할당하고 또 그것들을 연결하여 마치 배열처럼 사용하는 기법이 바로 링크드 리스트이다.링크드 리스트의 장점으로는 프로그래머가 미리 공간을 할당할 필요 없이 필요할때마다 공간을 할당 받을 수 있도록 설계가 가능하다. 그러기 때문에 필요한 변수의 크기를 모를 경우에는 배열보다 효율적이다. 하지만 링크드 리스트에도 단점은 있다. 다음 노드의 주소를가리키기 위해 4byte(32비트 운영체제 기준)의 공간이 낭비된다. 또, 인덱스로 해당 주소에접근하는 것이 아닌 노드의 첫 번째를 가리키는 Head라는 포인터 변수를 통해서 순차적으로 접근하는 단점으로 인해 검색속도가 느리다는 단점이있다.(3번지 주소까지 가기 위해서는 1, 2번 주소지를 거쳐야 갈 수 있다.)
  5. 5. 다음은 링크드 리스트를 구현한 소스이다.#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct tagNode{ char Name[20]; struct tagNode* NextNode;}NODE; 구조체로 이루어져 있는 링크드 리스트. Name은 데이터를 담을 변수로 데이터가 들어가며, tagNode*는 다음 노드의 주소를 가리킬 포인터 변수이다.NODE* CreateNode(char name[]){ NODE* NewNode = (NODE*)malloc(sizeof(NODE)); strcpy(NewNode -> Name, name); NewNode -> NextNode = NULL; return NewNode;} NODE를 생성하는 함수이다. 인자로는 해당 노드에 들어갈 값을 저장하기 위한 값을 받고있다. NewNode라는 포인터를 생성후 그 해당하는 주소에 malloc함수로 공간을 동적할당하고 있다.void ConnectNode(NODE** Head, NODE* Node){ if(NULL == (*Head))
  6. 6. { *Head = Node; } else { NODE* Current = *Head; while(Current -> nextNode != NULL) { Current = Current -> NextNode; } Current -> NextNode = Node; }} 인자로는 첫 노드를 가리키는 Head의 주소값과 연결한 노드를 인자로 받는다. 여기서 헤드가 가리키는 노드가 없는(NULL)새로운 노드라면, main에 선언한 Head값 자체를 바꾸기위해 포인터 Head의 주소값을 가져오기 때문에 결과적으론 이중 포인터를 사용해야 한다.노드의 맨 마지막에 삽입할 경우의 수는 두 가지가 있다. 1. Head가 NULL일 경우(텅 빈 노드) 2. Head가 NULL이 아닐 경우(하나 이상의 연결된 노드) 1번의 경우는 Head의 다음 노드에 새 노드의 주소값을 넣으면 되지만, 2번의 경우엔 끝노드를 찾아서(NULL이 있는곳) 연결 해 줘야 한다. NODE* Current;를 선언하는 이유는Head의 값을 바꾸지 않고 연결된 다른 노드에 접근하기 위해서 사용한다.void PrintNode(NODE* Head, int index){ NODE* Current = Head;
  7. 7. while(Current != NULL && 0 < index) { index--; Current = Current -> NextNode; } printf(“%sn”, Current -> Name);} 노드의 값을 출력하는 함수이다. 인자로는 Head와 몇 번째 노드를 출력할건지 정하는 변수이다. while의 경우 Current != NULL은 NULL일 경우엔 노드의 끝이므로 이 이상 접근을하지않기 위해 쓴다.int GetCountNode(NODE * Head){ NODE* Current = Head; int count = 0; while(Current != NULL) { count++; Current = Current -> NextNode; } return count;}PrintNode로 전체 출력을 하기를 원할 경우 노드의 개수를 알아내는데 사용되는 함수이다.void InsertNode(NODE** Head, NODE* ConnectNode, int index){ if(0 == index)
  8. 8. { ConnectNode -> NextNode = (*Head); *Head = ConnectNode; } else { NODE* Current = *Head; while(0 < (--index)) { Current = Current -> NextNode; } ConnectNode -> NextNode = Current -> NextNode; Current -> NextNode = ConnectNode; }}노드와 노드 사이에 새로운 노드를 삽입하는 함수이다. 1. 4번지 주소의 다음 노드 주소값을 2번지 노드의 주소값으로 변경 2. 2번지 노드의 주소값을 4번지 노드의 주소로 변경void DestroyNode(NODE** Head, int index){ NODE* Remove = *Head; while(Remove != NULL && 0<(--index))
  9. 9. { Remove = Remove -> NextNode; } if(*Head == Remove) { *Head = Remove -> NextNode; } else { NODE* Current = *Head; while(Current != NULL && Current -> NextNode != Remove) { Current = Current -> NextNode; } if(Current != NULL) { Current -> NextNode = Remove -> NextNode; } } free(Remove);} 삭제 연산은 삽입 연산보다 훨씬 간단하다. 삭제할 노드의 앞노드(1번노드)의 다음 주소를삭제할 노드의 다음 주소를 가리키도록만 하면 된다. 프로그래머가 할당하는 공간은 프로그래머가 해제해 줘야한다. 그러기 위해서 사용하는 함수 free가 있다. 인자는 해제할 메모리의 주소값만 넘기면 되기 때문에 삭제할 노드의 주소를 보내주면 된다.구조체 다른 종류의 데이터를 하나로 묶어서 사용하는 데이터 결합법을 말한다.각기 다른 형이나 다른 의미의 값을 가지고 있는 배열들을 한 번에 나타낼 수 있도록 구현한 자료구 조형이다.
  10. 10. struct 구조체 이름 { 자료형 자료이름; 자료형 자료이름; }과 같이 정의 할 수 있으며, 정의를 할 때에는 다음의 조건이 따른다.①구조체 정의에서 바로 초기화 할 수 없다.②구조체 선언은 문자에 해당되기 때문에 끝마친 후 ;을 붙여 주어야 한다.구조체를 통해서 여러개의 테이타 값을 묶을 수 있게 하여 연결리스트를 구현 할 수 있도록한다.4)알고리즘 계획① 다항식의 표현 DATA LINK1) 각 노드의 구조체 배열에서 DATA를 저장하는 배열과 다른 노드를 가리킬 수 있는 LINK가 존재한다. 이 때 DATA는 처리하는 값을 저장하는 배열이고, LINK는 다음 노드를 가리키는 포인터의 역할을 한다.다항식을 구현하기 위해서는,2) 다항식의 각 항을 계수부분 지수부분으로 나누어 생각한다. DATA의 배열도 계수와 지수를 저장할 수 있는 구조체를 선언한다. 계수부분 지수부분
  11. 11. 즉, DATA- DATA-지 LINK 계수부분 수부분과 같이 한 노드가 만들어지게 된다.3) 이러한 노드를 다항식에서 항의 개수만큼 LINK를 이용해 다음 항을 가리키고 다음 항을 가리키는 식으로 한 개의 다항식에 대해 한 개의 연결리스트를 만들어준다.② 다항식의 덧셈과 뺄셈1) 연결리스트로 작성 된 다항식1과 다항식2에 대해서 지수부분이 같은 노드끼리 연산을 해준 다.2) 다항식 3을 연결리스트로 작성하게 되는데, 이 때 1과2로 연산된 값을 3에 저장한다.3) 1과 2에 같은 지수부분이 없어서 연산되지 않은 나머지 항들은 그대로 복사되어서 3에저 장된다.4) 다항식의 연산을 마쳐서 3에 저장된 결과 값을 출력한다.③ 다항식의 곱셈1) 다항식 1의 노드와 다항식2의 노드의 계수부분은 곱셈연산을 하고 지수부분은 더하기 연산 을 해준다.2) 다항식1의 노드와 다항식2의 노드는 서로의 노드가 모두 순서쌍을 한 번 씩은 이루어야된 다.3) 순서쌍을 이루어서 연산 된 결과 값은 새로운 연결리스트 3에 저장된다.4) 각 노드들을 모두 더할 수 있도록, 위에서 작성하였던 ADD연산을 한 번 더 해준다.5) 정리 되어 3에 저장된 결과 값을 출력한다.④ 다항식의 나눗셈1) 나누는 다항식의 최고차항이 나눠지는 최고차항과 같아지게 할 수 있는 X가 계속해서 몫 이 될 수 있다.2) 계수의 계산은, p(x)의 계수 = s(x)계수*q(x) 계수, q(x)계수는 p/s과 같이 된다.3) 계속 최고차항에 맞춰서 X가 곱해져서 나눠지는 다항식에 그 결과 값을 뺄셈을 하고 있다. 이 때 곱해지는 차수가 0이거나 나머지가 0이면 스톱한다. 만약 뺄셈을 하다가 다항식이 남게 되면 그 남은 다항식은 나머지가 된다.
  12. 12. 5)소스 구현①소스 분석#include <stdio.h>#include <stdlib.h>typedef struct polynomial{ int degree; //차수 double coef;//계수 struct polynomial *link;}polynomial;typedef struct node{ int l; polynomial *s; polynomial *f;//다음을 가리킬 link}node;void st(node *point) //초기화{ point->l=0; point->s=point->f=NULL;}void insert_node(node *point,double coef,int degree){ //char *temp;
  13. 13. polynomial *temp=(polynomial *)malloc(sizeof(node));//연길리스트의 메모리할당을temp의 포인터 옮기는 정도에 따라 할당해줌 if(temp==NULL) { exit(1); } temp->coef=coef;//포인터로 polynomial타입의 구조체를 불러와서 계수를 삽입 temp->degree=degree;//차수를 삽입 if(point->f==NULL)//만약 연결리스트에서 빈값을 만나면 다시 temp로 포인터를 돌려줌 { point->s=point->f=temp; } else//그 이외의 경우 point는 { point->f->link=temp; point->f=temp; } point->l++;//포인터를 길이만큼 증가해줘서 마지막 자리를 가리키도록 설정}/*void polynomial_add(node point1, node point2, node point3){ polynomial *a=point1-> *///다항식 출력void print(node *point){ polynomial *p=point->s;//p포인터를 point를 통해 연결리스트의 처음 자리인s의주소값을 받아옴 for(;p;p=p->link) { if(p->coef==0 || p->degree==0)//만약 계수나 차수가 모두 0이면 출력하지 않음 { printf(""); } else if(p->degree==1)//차수가 1이면 계수만 출력 { printf("%d",p->coef);
  14. 14. } else { printf("%dx^%d",p->coef,p->degree); //계수가나 지수가 0이 아니면 계수x^지수 형태로 표시 } if(p->link==NULL)//P가 가리킨 곳이 빈값이면 아무것도 출력하지 않음. { printf(""); } else//값이 있는경우 가운데에 +를 출력 { printf(" + "); } } printf("n");}void poly_add(node *plist1, node *plist2, node *plist3){ polynomial *a=plist1->s;//다항식 1을 탐색할 포인터 polynomial *b=plist2->s;//다항식 2를 탐색할 포인터 int sum;//계수를 담을 변수 while(a&&b) { if(a->coef == b->coef)//지수가 같은 경우 { sum=a->coef+b->coef;//a,b 받은 계수과 차수를 coef구조체에 저장 if(sum!=0) { insert_node(plist3,sum,a->degree);//삽입함수를 불러옴,다항식1의 계수를 저장하는 polynomial구조체. 앞에서 계산 해준 sum은 계수로 저장.a는 다항식1의 차수를 가리킴. } b=b->link;//둘다 연결리스트의 link를 가리키게 함. a=a->link; } else if(a->degree >b->degree) {
  15. 15. insert_node(plist3,a->coef,a->degree);//차수를 가리키고 있을때,다항식3번째=1+2의 결과값을 저장. a=a->link; } else { insert_node(plist3,b->coef,b->degree); b=b->link; } for(;a!=NULL;a=a->link) { insert_node(plist3,a->coef,a->degree); } for(;b!=NULL;b=b->link) { insert_node(plist3,b->coef,b->degree); } }}void main(){ node list1, list2, list3; //다항식 입력받을 변수 선언 double a; int b; //항의 계수와 지수를 입력받기 위한 변수 st(&list1);//st 함수 호출로 공백 리스트 st(&list2); st(&list3); //다항식1을 입력받는 부분 printf("다항식1의 항(계수,지수)을 입력하세요. (0 0 이면 입력종료)n"); while (1) { scanf("%f %d",&a,&b); if (a==0.0 && b==0) {
  16. 16. break; } insert_node(&list1, a, b); } printf("다항식1 : "); print(&list1); //다항식1 출력 printf("n"); //다항식2을 입력받는 부분 printf("다항식2의 항(계수,지수)을 입력하세요. (0 0 이면 입력종료)n"); while (1) { scanf("%f %d",&a,&b); if (a==0.0 && b==0) { break; } insert_node(&list2, a, b); } printf("다항식2 : "); print(&list2); //다항식2 출력 printf("n"); // 다항식3 = 다항식1 + 다항식2 poly_add(&list1, &list2, &list3); printf("결과 : "); print(&list3); //다항식3 출력}
  17. 17. 7)최종소스#include <stdio.h>#include <stdlib.h>// 연결리스트 노드의 구조typedef struct listnode{ double coef; int expon; struct listnode *link;} listnode;// 연결리스트의 헤더typedef struct listheader{ int length; listnode *head; listnode *tail;} listheader;//초기화 함수int reset(listheader *plist){ plist->length=0; plist->head=plist->tail=NULL; return 0;}//plist는 연결 리스트의 헤더를 가르키는 포인터//expon는 지수 coef는 계수int poly_make(listheader *plist,double coef,int expon){ listnode *n=(listnode*)malloc(sizeof(listnode)); n->coef=coef; n->expon=expon;
  18. 18. n->link=NULL; if(plist->tail==NULL) { plist->head=plist->tail=n; } else { plist->tail->link=n; plist->tail=n; } plist->length++; return 0;}//list3 = list1 + list2int poly_add(listheader *plist1,listheader *plist2, listheader *plist3){ double sum; listnode *a=plist1->head; listnode *b=plist2->head; while(a,b) { if(a->expon == b->expon) { sum=a->coef+b->coef; if(sum!=0) { poly_make(plist3, sum, a->expon); a=a->link; b=b->link; } } else if(a->expon > b->expon) { poly_make(plist3, a->coef, a->expon); a=a->link; } else { poly_make(plist3, b->coef, b->expon);
  19. 19. b=b->link; } } return 0;}//출력 하기 위한 함수int poly_print(listheader *plist){ listnode *p = plist->head; for(1; p; p = p->link) { printf("%.1fX^%d", p->coef, p->expon); if(p->link!=NULL) { printf(" + "); } } printf("n"); return 0;}//메모리 해제 함수int poly_delete(listheader *plist){ listnode *n=plist->head; listnode *del; while(n->link!=NULL) { del=n; n=del->link; plist->head=n; free(del); } free(n); return 0;}//메인 함수int main()
  20. 20. { listheader list1, list2, list3; //리스트 변수 선언 // 연결 리스트이 초기화 reset(&list1); reset(&list2); reset(&list3); // P(X)를 생성 poly_make(&list1, -3.7, 3); poly_make(&list1, 2.5, 2); poly_make(&list1, 1, 1); // S(X)를 생성 poly_make(&list2, 8.2, 3); poly_make(&list2, -3.1, 2); poly_make(&list2, 10.2, 1); // T(X)를 생성 // T(X)=P(X)+S(X) poly_add(&list1, &list2, &list3); printf("P(X)의 다항식 : "); poly_print(&list1); printf("S(X)의 다항식 : "); poly_print(&list2); printf("T(X)의 다항식 : "); poly_print(&list3); // 할당한 메모리의 리스트를 해제 poly_delete(&list1); poly_delete(&list2); poly_delete(&list3); return 0;}
  21. 21. •실행 화면8)시간복잡도/공간복잡도

×