단순 연결리스트(simply linked list)로 스택을 구현해보자.
리스트뿐만 아니라 스택과 큐도 연결리스트로 구현할 수 있다. 똑같이 구조체로 노드를 정의하고 시작하면 된다.
일단 스택은 top이 head가 된다. 위에서부터 삽입하고 삭제하는거 잊지말기~
이것도 두 가지 방법이 있는데 전역변수를 사용할 것인지 말것인지에 따라 나눠보았다. 왜 전역변수의 유무에 집착하냐고 물어보고 싶으면 저 말고 제 교수님께 여쭤보세요.
사용한 함수들은 다음과 같음:
- init(): top을 초기화한다.
- is_empty(): 스택이 비었는지 확인한다.
- push(value): 요소를 삽입한다.
- pop(): top을 삭제한다. (스택은 LIFO이기 때문에 무조건 맨 위의 요소를 삭제한다. User Input으로 못 받아옴!!!!)
- peek(): top을 반환한다. 삭제하지는 않음.
- print_all(): 스택 안의 모든 요소를 순차적으로 출력한다.
이번에도 is_full()은 굳이 쓸 필요가 없을 것 같아서 안씀.
(1) 전역변수 사용
Node* top으로 헤드포인터 정의하고 삽입과 삭제 연산을 각각 해주면 된다.
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
|
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define ERROR_VALUE -300000
typedef struct LinkedNode {
int data;
struct LinkedNode* link;
}Node;
Node* top;
void init() { top = NULL; }
int is_empty() { return (top == NULL); }
void push(int value) {
Node* n = (Node*)malloc(sizeof(Node));
n->data = value;
n->link = top; //노드 n의 링크필드가 top이 가리키던 노드를 가리키게 한다
top = n; //top이 노드 n을 가리키게 한다
}
int pop() {
Node* removed;
int value;
if (is_empty()) {
printf("Stack Empty Error!\n");
return ERROR_VALUE;
}
else {
removed = top; //removed를 반환할 것이다
top = removed->link;
value = removed->data;
free(removed);
return value;
}
}
int peek() {
int value;
if (is_empty()) {
printf("Stack Empty Error!\n");
return ERROR_VALUE;
}
else {
value = top->data;
return value;
/*
이 부분은 그냥 return top->data 해도 된다
*/
}
}
int size() {
Node* p; //전부 방문하기 위한 노드 p
int count = 0;
for (p = top; p != NULL; p = p->link)
count++;
return count;
}
void print_all() {
Node* p;
printf("STACK STATUS: size=%d\n", size());
for (p = top; p != NULL; p = p->link)
printf("[%2d]->", p->data);
printf("NULL\n");
}
int main(void) {
int sel, value;
init();
while (1) {
do {
printf("1.PUSH 2.POP 3.PEEK 4.STATUS 0.EXIT :");
scanf("%d", &sel);
} while (sel < 0 || sel > 4);
if (sel == 1) {
printf("Enter value to push from top : ");
scanf("%d", &value);
push(value);
}
else if (sel == 2) {
value = pop(); //스택이므로 user input으로 임의대로 pop할 수 없다.
if (value != ERROR_VALUE)
printf("[%2d] has been popped out from STACK\n", value);
}
else if (sel == 3) {
value = peek();
if (value != ERROR_VALUE)
printf("[%2d] is the top value of STACK\n", value);
}
else if (sel == 4) {
if (is_empty()) printf("Stack is Empty!\n");
else print_all();
}
else break;
}
printf("\nE N D O F P R O G R A M");
return 0;
}
|
cs |
(2) 전역변수 미사용
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
|
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define ERROR_VALUE -300000
typedef struct LinkedNode {
int data;
struct LinkedNode* link;
}Node;
int is_empty(Node** top) { return (*top == NULL); }
void push(Node**top, int value) {
Node* n = (Node*)malloc(sizeof(Node));
n->data = value;
n->link = *top;
*top = n;
}
int pop(Node** top) {
Node* removed;
int value;
if (is_empty(top)) {
printf("Stack Empty Error!\n");
return ERROR_VALUE;
}
else {
removed = *top;
*top = removed->link;
value = removed->data;
free(removed);
return value;
}
}
int peek(Node** top) {
int value;
if (is_empty(top)) {
printf("Stack Empty Error!\n");
return ERROR_VALUE;
}
else {
value = (*top)->data;
return value;
}
}
int size(Node** top) {
Node* p;
int count = 0;
for (p = *top; p != NULL; p = p->link)
count++;
return count;
}
void print_all(Node** top) {
Node* p;
printf("STACK STATUS: size=%d\n", size(top));
for (p = *top; p != NULL; p = p->link)
printf("[%2d]->", p->data);
printf("NULL\n");
}
int main(void) {
Node* top = NULL; //main에서 바로 초기화(아직도 함수로 할 줄 모름)
int sel, value;
while (1) {
do {
printf("1.PUSH 2.POP 3.PEEK 4.STATUS 0.EXIT :");
scanf("%d", &sel);
} while (sel < 0 || sel > 4);
if (sel == 1) {
printf("Enter value to push from top : ");
scanf("%d", &value);
push(&top, value);
}
else if (sel == 2) {
value = pop(&top); //스택이므로 user input으로 임의대로 pop할 수 없다.
if (value != ERROR_VALUE)
printf("[%2d] has been popped out from STACK\n", value);
}
else if (sel == 3) {
value = peek(&top);
if (value != ERROR_VALUE)
printf("[%2d] is the top value of STACK\n", value);
}
else if (sel == 4) {
if (is_empty(&top)) printf("Stack is Empty!\n");
else print_all(&top);
}
else break;
}
printf("\nE N D O F P R O G R A M");
return 0;
}
|
cs |
<결과 창>
++ 참고로
1
2
3
4
|
typedef struct LinkedNode {
int data;
struct LinkedNode* link;
}Node;
|
cs |
여기 구조체 정의하면서 안에 다시 구조체로 링크필드를 만드는데, struct를 빼먹으면 큰일난다. 그냥 코드 전체가 에러창에 뜸. 밑에 Node;가 입력이 되면서 구조체 정의가 완료된 걸로 보기 때문이다. 아무 생각 없이 안썼다가 한시간 정도 해맸다 역시 머리가 나쁘면 몸이 고생ㅎㅎ
'coding > Data Structure(C)' 카테고리의 다른 글
[C] 이진트리의 순회 (0) | 2020.12.12 |
---|---|
[C] 트리와 이진트리 (0) | 2020.12.12 |
[C] 큐와 연결리스트 (0) | 2020.12.12 |
[C] 리스트와 연결리스트(2) (0) | 2020.12.11 |
[C] 리스트와 연결리스트(1) (0) | 2020.12.11 |