Available Space List (1)
- Available spcae list 또는 avail lsit는 우리가 새로운 node가 필요할 때 평가해서 그 때 그 떄 사용할 수 있습니다.
- 또한 처음에는 avail는 NULL로 초기화 됩니다.
- 우리는 node를 malloc()하거나, free()하는 것이 아니라, 아래서 볼 getNode()이나 retNode()를 사용하면 됩니다.

이는 getNode()메소드의 기본적인 작동 방식을 묘사한 것입니다. avail이 있다면 이 avail은 avail->link를 가리키게 하고 avail을 필요로 하는 node에게 avail을 주어주는 방식으로 작동됩니다.

이는 retNode()메소드의 기본적인 작동 방식을 묘사한 것입니다. node->link를 avail을 가리키게 하고 node가 이제 avail의 head로 만들어 주면 끝입니다. 이렇게 하면 node가 나중에 필요할 때 쓸 수 있는 avail로 들어가게 됩니다.
이럴 활용해서 저번에 구현한 polynomials를 합치는 logic을 작성해보겠습니다.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_QUEUES 10 /* maximum number of stacks */ #define ERROR_KEY -100 #define MALLOC(p, s) \ if (!((p) = malloc(s))) \ { \ fprintf(stderr, "Insufficient memory"); \ exit(EXIT_FAILURE); \ } typedef struct polyNode { float coef; int expon; struct polyNode *link; } * polyPointer; polyPointer a, b; polyPointer avail = NULL; polyPointer getNode(void) { polyPointer node; if (avail) { node = avail; avail = avail->link; } else MALLOC(node, sizeof(struct polyNode)); return node; } void retNode(polyPointer node) { node->link = avail; avail = node; } int COMPARE(int expon1, int expon2) { if (expon1 < expon2) return -1; else if (expon1 > expon2) return 1; else return 0; } void attach(float coefficient, int exponent, polyPointer *ptr) { polyPointer temp; temp = getNode(); temp->coef = coefficient; temp->expon = exponent; temp->link = (*ptr)->link; (*ptr)->link = temp; *ptr = temp; } polyPointer padd(polyPointer a, polyPointer b) { float sum; polyPointer c, rear, temp; MALLOC(rear, sizeof(*rear)); rear->link = NULL; c = rear; while (a && b) { switch (COMPARE(a->expon, b->expon)) { case -1: attach(b->coef, b->expon, &rear); b = b->link; break; case 0: sum = a->coef + b->coef; if (sum) { attach(sum, a->expon, &rear); } a = a->link; b = b->link; break; case 1: attach(a->coef, a->expon, &rear); a = a->link; break; } } /* copy rest of list a and then list b */ for (; a; a = a->link) attach(a->coef, a->expon, &rear); for (; b; b = b->link) attach(b->coef, b->expon, &rear); /* delete extra initial node */ temp = c; c = c->link; retNode(temp); // free(temp); return c; } void insert(polyPointer *first, polyPointer x, float coef, int expon) { polyPointer temp; MALLOC(temp, sizeof(*temp)); temp->coef = coef; temp->expon = expon; if (*first) { temp->link = x->link; x->link = temp; } else { temp->link = NULL; *first = temp; } } void printList(polyPointer first) { printf("The list contains: "); for (; first; first = first->link) { if (first->expon != 0) { if (first->link == NULL) { printf("%.2fx^%d", first->coef, first->expon); putchar('\n'); return; } printf("%.2fx^%d + ", first->coef, first->expon); } else { printf("%.2f", first->coef); putchar('\n'); return; } } printf("\n"); } void readPolynomial(polyPointer *pPoint, FILE *fp_read) { int i, number, expon; float coef; polyPointer temp = NULL; fscanf(fp_read, "%d", &number); for (i = 0; i < number; i++) { fscanf(fp_read, "%f %d", &coef, &expon); insert(pPoint, temp, coef, expon); if (i == 0) { temp = *pPoint; } else { temp = temp->link; } } } void erase(polyPointer *ptr) { polyPointer temp; while (*ptr) { temp = *ptr; *ptr = (*ptr)->link; retNode(temp); // free(temp); } } int main(void) { FILE *fp_read; fp_read = fopen("a.txt", "r"); polyPointer a = NULL; readPolynomial(&a, fp_read); polyPointer b = NULL; fp_read = fopen("b.txt", "r"); readPolynomial(&b, fp_read); fclose(fp_read); polyPointer resultPolynomial = padd(a, b); printList(resultPolynomial); erase(&resultPolynomial); return 0; }
Available Space List (2)
cerase()는 circular list에서 avail로 이주시키는 함수입니다.

이는 cerase()메소드의 기본적인 작동 방식을 묘사합니다. (*ptr)->link를 일단 temp라고 합니다. 그리고 (*ptr)->link를 avail을 가리키게 하고 마지막으로 avail을 temp로 하게 되면 신기하게도 circular-list가 avail에 추가되게 됩니다.
Available Space List 총 정리

Zero Polynomial
또한 zero polynomials이라는 circular-list에서의 special case를 피하기 위해 몇가지 규칙을 정했습니다.
- 각각의 polynomial는 최소한 하나의 노드를 가지고 있어야 합니다.
- 또한 expon과 coef필드는 관계가 없습니다.

Additional List Operations (1)
Invertion Operations for Chains
이는 노드의 순서를 거꾸로 바꾸는 linked-list의 함수입니다. linked-list에서 순서를 바꾸려면 lead, middle, trail이라는 3개의 포인터가 필요하게 됩니다.

invert()함수의 기본 동작 방식은 위와 같습니다. 일단 middle, trail을 lead외에 추가적으로 생성해 줍니다. 그리고 lead가 NULL이 아닌 동안 trail = middle, middle = lead, lead = lead->link, middle->link = trail을 해주게 되면 최종적으로 lead가 NULL에 도달하는 순간 노드가 역순으로 되어 있을 겁니다.
Concatenating singly linked lists
이는 기본적인 singly linked-list를 이어 붙이는 함수입니다.

이는 인자로 받은 head포인터 2개 ptr1과 ptr2가 인자로 받아 들여지면 for(temp = ptr1; temp->link; temp = temp->link);로 temp를 ptr1 linked-list의 끝을 가리키게 하고 마지막으로 temp->link = ptr2를 하게 된다면 끝나게 됩니다.
중간 정리

Inserting at the front of a circular list
이는 circular-list에서 맨 앞에 node를 추가하는 함수입니다.

이는 circular-list의 맨 마지막 node와 추가할 node를 인자로 받습니다. 그리고 circular-list가 비었을 때와 비지 않았을 때를 나누어서 로직을 처리해주어야 합니다. 우선 list가 비었을 때에는 (*last) = node를 하고 node->link = node;를 해주면 끝입니다. 그다음으로는 list에 node가 있다면 node->link = (*last)->link를 하고 (*last)->link = node를 하면 됩니다.
Finding the length of a circular list
circular list의 길이를 알아내는 코드는 어떻게 짜는지 알아보겠습니다. 그냥 circular-list의 last 노드를 인자로 받습니다. 그냥 counter를 만들어주고 last부터 시작해서 temp = temp->link를 매번 해주고 temp != last)인동안 do - while문을 조져주면 counter에 circular-list의 크기가 들어가게 됩니다.
중간정리

'School > DataStructure' 카테고리의 다른 글
Data-Structure - Tree (0) | 2022.04.14 |
---|---|
Data-Structure - Linked-List ( Application - 3 ) (0) | 2022.04.08 |
Data-Structure - Linked list ( Applications ) (0) | 2022.04.05 |
Data-Structure - Linked Lists (0) | 2022.04.01 |
Data-Structure - Circular Queues (0) | 2022.04.01 |