1. 개요
후입선출(後入先出, Last In First Out; LIFO) 의 자료구조로, 상자의 형태를 한 자료구조이다.
데이터의 삽입을 Push, 데이터의 출력을 Pop이라고 하며, 스택을 크게 두 가지로 나누면
Ascending Stack VS Descending Stack으로 나눌 수 있다.
스택은 배열과 링크드 리스트로 구현할 수 있는데, 여기서는 링크드리스트를 이용한 스택을 구현해 보겠다.
2. 코드 구현
2-1. define structure
typedef struct _stacknode Snode;
struct _stacknode {
DataType data;
Snode *next;
};
typedef struct _stack {
Snode *head;
Snode *tail;
Snode *cur;
}Stack;
스택관리구조체 Stack은 링크드리스트 구조체처럼 head와 tail을 고정적으로 가리키는 노드포인터와 현재 노드를 가리키는 cur 포인터로 이루어져있다.
2-2. Init Stack
void initStack(Stack *sPtr) {
sPtr->head = (Snode *)malloc(sizeof(Snode)); //헤드 노드 생성
assert(sPtr->head!=NULL);
sPtr->tail = (Snode *)malloc(sizeof(Snode)); //테일 노드 생성
assert(sPtr->tail!=NULL);
/*헤드노드가 테일노드를, 테일노드가 헤드노드를 가리키게 함*/
sPtr->head->next=sPtr->tail;
sPtr->tail->next=sPtr->tail;
sPtr->cur = NULL;
return ;
}
헤드노드와 테일노드를 메모리 할당해주고 서로 가리키게 해준다
2-3. Push
/* stack에 데이터 저장하기 */
int push(Stack *sPtr, DataType inData) {
sPtr->cur = (Snode *)malloc(sizeof(Snode)); //새로운 노드 생성
// 메모리 할당 실패하면 push실패
if(sPtr->cur==NULL) {
return FALSE;
}
//노드를 헤드노드 바로 뒤에 노드 추가
sPtr->cur->next=sPtr->head->next;
sPtr->head->next=sPtr->cur;
sPtr->cur->data = inData; //데이터 복사
return TRUE;
}
전달인자로 스택구조체의 주소와 삽입할 데이터를 받는다.
새 노드를 할당하기위해 메모리를 할당하고 위로 쌓이는 것이므로 (처음 삽입하는경우) 헤드노드 바로 뒤에 노드를 추가해주는데, 두 번째 삽입부터는 노드가 이미 하나있기때문에 그 노드의 뒤로 삽입을 해야한다. 따라서, 새로 할당받은 노드의 다음주소에 그 이전 노드를 가리키게 하고 이전 노드는 새로 할당받은 노드를 가리키게 한다.
2-4. Pop
int pop(Stack *sPtr, DataType *popData) {
// stack이 비어있으면 pop실패
if(sPtr->head->next == sPtr->tail) {
return FALSE;
}
*popData = sPtr->head->next->data;
sPtr->cur = sPtr->head->next;
sPtr->head->next = sPtr->head->next->next;
free(sPtr->cur);
return TRUE;
}
제일 위에있는게 먼저 나가야하므로 popData에 가장 위에있는 노드의 data를 넣어주고, 제일 위에 있는 노드에 이어져 있는 선을 끊어주고 다음 노드와 이어주게 한다. 그리고 메모리를 해제