[자료구조 - C언어] 자료구조 [15강-18강] 복습 및 정리
2022. 11. 17. 02:39ㆍCS/자료구조
728x90
//공부 기록용 포스팅입니다. 틀린 부분이 있을 경우 댓글로 알려주시면 감사합니다! 😎
1. 스택과 큐의 비교
2. 연결 리스트로 구현한 자료구조
2-1. 스택
- 연결 리스트의 맨 앞이 노드를 삽입/삭제하기에 편하다→ 맨 앞을 스택의 top으로 한다.
typedef int Item;
typedef struct stack_type *Stack;
struct node{
Item data;
struct node *next;
}
struct stack_type{
struct node *top;
}
//스택의 생성
Stack create(){
Stack s = malloc(sizeof(struct stack_type));
s->top = NULL;
return s;
}
//삽입
void push(Stack s, Item i){
struct node *new_node = malloc(sizeof(struct node));
new_node->data = i;
new_node->next = s->top;
s->top = new_node;
}
//삭제
Item pop(Stack s){
struct node *old_top;
Item i;
//스택이 비지 않았을 때: s->top != NULL
old_top = s->top;
i = old_top->data;
s->top = old_top->next;
free(old_top);
return i;
}
2-2. 큐
- 연결 리스트의 첫 번째 노드에서는 삽입과 삭제가 둘 다 가능하나, 마지막 노드의 삭제는 어렵다.
⇒ 첫 번째 노드를 삭제하는 역할의 rear, 마지막 노드를 삽입하는 역할의 front - 큐는 배열보다 연결 리스트로 구현하는 것이 간편하다.
typedef int Item;
typedef struct stack_type *Stack;
struct node{
Item data;
struct node *next;
};
struct queue_type{
struct node *front;
struct node *rear;
int size;
}
//큐의 생성
Queue create(){
Queue q = malloc(sizeof(struct queue_type));
q->front = NULL;
q->rear = NULL;
q->size = 0;
return q;
}
//삽입
void enqueue(Queue q, Item i){
struct node *new_node = malloc(sizeof(struct node));
new_node->data = i;
new_node->next = NULL;
if(q->front == NULL){
q->front = new_node;
q->rear = new_node;
}
else{
q->rear->next = new_node;
q->rear = new_node;
}
q->size++;
}
//삭제
Item dequeue(Queue q){
struct node *old_front;
Item i;
//큐가 비지 않았을 때: q->size != 0
old_front = q->front;
i = old_front->data;
q->front = old->front->next;
//큐에 노드가 하나 있을 때
if(q->front == NULL)
q->rear = NULL;
free(old_front);
q->size--;
return i;
}
3. 배열로 구현한 자료구조
3-1. 스택
- 데이터를 저장할 *contents, top을 가리키는 변수 top, 배열의 크기를 저장하는 size 가 하나의 구조체
- 스택을 동적 할당하고, 내부의 데이터인 contents도 할당받아야 함
typedef int Item;
typedef struct stack_type *Stack;
struct stack_type{
Item *contents;
int top;
int size;
}
//스택의 생성
Stack create(){
Stack s = malloc(sizeof(struct stack_type));
s->contents = (Item *)malloc(배열의 크기 * sizeof(Item));
s->top = -1;
s->size = 배열의 크기;
return s;
}
//삽입
void push(Stack s, Item i){
if(s->top +1 == s->size)
reallocateStack(s);
s->top++;
s->contents[s->top] = i;
}
//배열 재할당
void reallocate(Stack s){
Item *tmp = (Item *)malloc(2 * s->size * sizeof(Item));
for(int i=0; i<s->size; i++){
tmp[i] = s->contents[i];
free(s->contents);
s->contents = tmp;
s->size *= 2;
}
//삭제
Item pop(Stack s){
//스택이 비지 않았을 때: s->top != -1
s->top--;
return s->contents[s->top+1];
}
3-2. 큐
- 배열로 구현한 큐는 front부터 rear까지 빈공간이 없어야 한다.
- 배열로 구현한 큐는
- 인덱스의 범위와
- 배열의 모든 칸을 사용하고 있어야 추가 reallocate를 받을 수 있기 때문에
⇒ 환형배열을 사용해야 한다 ~ reallocate도 스택과 다르게 해줘야 함
- 스택을 동적 할당하고, 내부의 데이터인 contents도 할당받아야 함
typedef int Item;
typedef struct queue_type *Queue;
struct queue_type{
Item *contents;
int front, rear, size, capacity;
}
//큐의 생성
Queue create(){
Queue q = malloc(sizeof(struct queue_type));
q->contents = (Item *)malloc(배열의 크기 * sizeof(Item));
q->front = 0;
q->rear = -1;
q->size = 0;
q->capacity = 배열의 크기;
return q;
}
//삽입
void enqueue(Queue q, Item i){
if(q->size == q->capacity)
reallocate();
q->rear = (q->rear +1) % q->capacity;
q->contents[q->rear] = i;
q->size++;
}
//재할당
void reallocate(Queue q){
Item *tmp = (Item *)malloc(2 * q->capacity * sizeof(Item));
int j = q->front;
for(int i=0; i<q->size; i++){
tmp[i] = q->contents[j];
j = (j+1) % q->capacity;
}
free(q->contents);
q->front = 0;
q->rear = q->size-1;
q->contents = tmp;
q->capacity *= 2;
}
//삭제
Item dequeue(Queue q){
//큐가 비지 않았을 때: q->size != 0
Item result = q->contents[q->front];
q->front = (q->front + 1) % q->capacity;
q->size--;
return result;
}
4. DFS와 BFS의 미로 찾기
4-1. 스택
while(1)
{
maze[cur.x][cur.y] = VISITED; //현재 위치를 방문했다고 표시
if(cur.x == n-1 && cur.y == n-1){
printf("Found the path.\\\\n");
break;
}
bool forwarded = false; //되돌아 나가야하는지를 알려줌
for(int dir = 0 ; dir<4; dir++){
if(movable(cur, dir)==1){
push(s, cur); //**이동할 수 있다면 현재 위치를 스택에 push
cur = move_to(cur, dir);
forwarded = true;
break;
}
}
if(!forwarded){ //**이동에 성공하지 못했다면 ~ 되돌아가야함
maze[cur.x][cur.y] = BACKTRACKED; //현재 위치를 되돌아간 위치라 표시
...
cur = pop(s); //**스택에서 pop한 위치가 새로운 현재 위치(cur)
}
}
4-2. 큐
enqueue(q, cur); //출발점을 큐에 넣고 시작
maze[0][0] = -1;
while(!is_empty(q)){
Position cur = dequeue(q); //**
for(int dir = 0; dir<4; dir++){
if(movable(cur, dir)){
Position p = move_to(cur, dir);
//**이동한 칸의 값 = 현재 위치 값 -1
maze[p.x][p.y] = maze[cur.x][cur.y] -1;
if(p.x == n-1 && p.y == n-1){
printf("Found the path.\\\\n");
//found = true;
break;
}
enqueue(q, p); //**이동한 위치가 출구가 아니라면 큐에 삽입
}
}
}
부경대학교 권오흠 교수님의 [c로 배우는 자료구조 및 여러 가지 예제 실습] 강의 정리입니다. 감사합니다.
728x90
'CS > 자료구조' 카테고리의 다른 글
[자료구조 - C언어] 자료구조 제19강: 시간복잡도와 점근적 분석(2), (3) (0) | 2022.11.17 |
---|---|
[자료구조 - C언어] 자료구조 제19강: 시간복잡도와 점근적 분석(1) (0) | 2022.11.17 |
[자료구조 - C언어] 자료구조 제18강: 큐의 개념과 응용 - 미로찾기 (1) | 2022.11.17 |
[자료구조 - C언어] 자료구조 제18강: 큐(queue)의 개념과 구현(2) (0) | 2022.11.16 |
[자료구조 - C언어] 자료구조 제18강: 큐(queue)의 개념과 구현(1) (0) | 2022.11.16 |