#include <stdio.h>
#include <stdlib.h>

struct Stack {
        struct Stack* next;
        int data;
};


int push(struct Stack* stack, int data) {
        struct Stack* newNode = malloc(sizeof(struct Stack));
        if (newNode == NULL) return -1;

        newNode->data = data;
        newNode->next = stack->next;
        stack->next = newNode;

        return 0;
}

int pop(struct Stack* stack, int* data) {
        struct Stack* popNode = stack->next; 
        if (popNode == NULL) return -1;  // pop할 노드가 NULL이면(스택에 데이터가 없음) 오류 리턴
 
        *data = popNode->data;  // pop할 데이터 저장
        stack->next = popNode->next;  // head가 가리키는 데이터를 pop할 노드가 가리키던 데이터로 이어줌
        free(popNode);  // head를 이어주었으므로 pop 노드는 삭제
        return 0;
}


/*
   element의 data와 같은 노드를 찾아서 삭제하는 함수.
   맨 앞에서부터 검색 후 삭제한다.
 */
int delete(struct Stack* stack, int element) {
        struct Stack* curPos = stack;
 
        while (curPos->next != NULL) {
                if (curPos->next->data == element) {  // 검색을 curPos의 next부터 
                        struct Stack* removeNode = curPos->next;
                        curPos->next = removeNode->next;
                        free(removeNode);
                        return 0;
                }
        }

        return -1;
}

/*
   스택을 생성하는 함수. 동적 배열을 사용하는 경우에 써야 하나,
   인터페이스의 일관성을 위해서 링크드리스트인 경우에도 추가함.
 */
int createStack(struct Stack* stack) {
        stack->next = NULL;
        return 0;
}

/*
   스택을 모두 지우는 함수
 */
int deleteStack(struct Stack* stack) {
        struct Stack* removeNode = stack->next;

        while (removeNode != NULL) {
                stack->next = removeNode->next;
                free(removeNode);
                removeNode = stack->next;
        }
}

/*
   beforeItem 다음에 item를 삽입하는 함수
 */
int insertAfter(struct Stack* stack, int beforeItem, int item) {
        struct Stack* curPos = stack->next;
 
        while (curPos) {
                if (curPos->data == beforeItem) {
                        struct Stack* newNode = malloc(sizeof(struct Stack));

                        newNode->next = curPos->next;
                        newNode->data = item;
                 
                        curPos->next = newNode;
                }
                curPos = curPos->next;
        }
        return -1;
}


/*
   모든 원소를 traverse하는 함수(디버깅용)
*/
int traverse(struct Stack* stack) {
        struct Stack* curPos = stack->next;

        while (curPos) {
                printf("%d ", curPos->data);
                curPos = curPos->next;
        }
        printf("\n");
        return 0;
}

void main() {
        printf("스택에 1, 2, 3을 넣은 후 3을 찾아서 삭제하고, pop을 실행합니다. 그리고 1 다음에 10을 삽입합니다..\n");
        struct Stack* stack = malloc(sizeof(struct Stack));

        createStack(stack);
        push(stack, 1);
        push(stack, 2);
        push(stack, 3);

        traverse(stack);
 
        struct Stack* deleteItem = malloc(sizeof(struct Stack));
        delete(stack, 3);
 
        traverse(stack);

        int data;
        pop(stack, &data);
 
        traverse(stack);

        insertAfter(stack, 1, 10);
 
        traverse(stack);
        deleteStack(stack);
        traverse(stack);
}

'알고리즘 > 자료구조' 카테고리의 다른 글

다리를 지나는 트럭 (Python)  (0) 2020.03.30

+ Recent posts