본문 바로가기

공부기록/자료구조알고리즘

자료구조+알고리즘 4일차

오늘은 스택에 대해 배웠다.

스택(stack)

4일차 (23.08.01)


  1. 이진탐색 복습
  2. 스택 함수 구현
  3. +) 스택 함수 응용해봄

스택(stack)은 데이터를 일시적으로 저장하기 위한 자료구조 중에 하나인데 후입선출 구조를 띰.

Last In First Out 즉 마지막에 넣어진 값이 첫번째로 나가는 형태이고.. 큐랑은 많이 다르지

데이터를 넣는 작업 : push

데이터를 빼내는 작업 : pop

데이터의 꼭대기 : top 

 

 

1. 이진 탐색 복습

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

int binary_search_desc(const int *arr, int size, int value) {
    int left = 0;
    int right = size - 1;
    while (left <= right) {
        int middle = left + (right - left) / 2;
        if (arr[middle] == value) {
            return middle;
        } else if (arr[middle] > value) { // 내림차순의 경우 '>'
            left = middle + 1;
        } else {
            right = middle - 1;
        }
    }
    return -1;
}

int main(void) {
    int nx;
    int ky;
    printf("이진검색 함수2\n");
    printf("요소 개수 : ");
    scanf("%d", &nx);
    int *x = calloc(nx, sizeof(int));

    printf("첫 번째 요소: ");
    scanf("%d", &x[0]);
    for (int i = 1; i < nx; i++) {
        do {
            printf("x[%d]: ", i);
            scanf("%d", &x[i]);
        } while (x[i] >= x[i - 1]); // 내림차순이므로 다음 값이 같거나 더 커야 함
    }
    printf("검색할 값: ");
    scanf("%d", &ky);

    int index = binary_search_desc(x, nx, ky);

    if (index != -1) {
        printf("검색 값 %d은(는) x[%d]에 있음.\n", ky, index);
    } else {
        printf("검색 값 %d은(는) 없음.\n", ky);
    }

    free(x);

    return 0;
}

없으면 없다고 알려줌
검색 값 있으면 이런식으로 알려줌

이런식으로 첫 번째 요소를 먼저 입력받고 그 다음 요소가 그 전의 요소보다 작아야만 다음으로 넘어가도록 while문을 돌렸고, 마지막에 검색할 값에서 찾는 값이 있으면 몇번째 요소인지를 알려주고, 없으면 없다고 뜬다.

 

 

 

2. 스택 구현

// 헤더파일(스택기능.h), 소스파일2개(메인.c/스택기능.c)
#include <stdio.h>
#include <stdlib.h>
// 헤더파일 선언

// 스택을 구현하는 구조체
typedef struct{
  int max; //스택의 용량 -> stk의 요소 갯수와 같아야 함.
  int ptr; // 스택포인터 -> 스택에 쌓여있는 데이터 개수, 스택 비어있으면 ptr 0/ 스택이 가득차있으면 max
  int *stk; //스택의 첫 요소에 대한포인터 -> 스택으로 사용할 배열을 가르키는 포인터
} IntStack;

/*--- 스택 초기화 ---*/
int Initialize(IntStack *s, int max){
  s->ptr =0; //처음 주소값은 0, 스택이 비어있어야 하니까
  if((s->stk = calloc(max,sizeof(int)))==NULL){
    s->max = 0; // 접근할 수 있는 skt[0], skt[1] ,... , skt[max-1]
    return -1;
  }
  s->max = max;
  return 0;
  
};

/*--- 스택 pop 데이터를 제거하는 함수 ---*/
// 꼭대기에서 제거합니다
int Pop(IntStack *s, int *x){
  if (s ->ptr <= 0) // 스택이 비어있는 경우
    return -1;
  
  *x = s -> stk[--s -> ptr]; // 감소를 시키면서 가져와야 한다
  return 0;
};


/*--- 스택 push 데이터를 추가하는 함수 ---*/
// 성공하면 0 반환, 실패하면 -1 반환

int Push(IntStack *s, int x){
  if (s -> ptr >= s -> max) // 스택이 가득차 있는 상태
    return -1;
  
  s -> stk[s->ptr++] = x;
  return 0;
};

/* --- 스택 peek 데이터를 제거하는 함수 ---*/
int Peek(IntStack * s, int *x){
  if (s->ptr <= 0) // 스택이 비어있는가?
      return -1;
  *x = s->stk[s->ptr-1];
  return 0;
};

/*--- 스택 clear 모든 데이터를 삭제하는 함수  ---*/
void Clear(IntStack *s){
  s->ptr = 0;
};




// main.c 구현
int main(void){
  IntStack s;
  if (Initialize(&s, 64) == -1){
    printf("스택 생성에 실패했습니다.");
    return 1;
  }
  while(1) {
    int menu, x;
    printf("현재 데이터 수: %d \n", s.ptr);
    printf("1.push 2.pop 3.peek 4.clear 5.종료\n");
    scanf("%d", &menu);
    if (menu == 1){
      Push(&s, x);
    }
    else if (menu == 2){
      Pop(&s, &x);
    }
    else if (menu == 3){
      Peek(& s, &x);
    }
    else if (menu == 4){
      Clear(&s);
    }
    else if (menu == 5){
      break;
    }
    
    
  }
  
  // Terminate(&s);
  free(s.stk);
  return 0;


  
}

이런식으로

 

push, pop, peek, clear 기능을 구현해보았다.

 

근데 해보니까 너무 심심해서 시각적으로 보이면 어떨까 싶었다. 그리고 나는 실제로 c를 할 때 visual studio 쓰니까 헤더파일이랑 소스파일 나눠서 구현해보면 어떨까 싶어서 나눠서 좀 멋있게 해봄.. 근데 peek 은 처음 보는데 어디에 쓰는건지 나중에 조금 더 공부해야겠다

3. 스택 함수 응용해봄

#pragma once
#define _CRT_SECURE_NO_WARNINGS


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

typedef struct {
	int max;
	int ptr;
	int* stk;

}IntStack;

int Initialize(IntStack* s, int max);
int Pop(IntStack* s, int* x);
int Push(IntStack* s, int max);
int Peek(IntStack* s, int* max);
void Clear(IntStack* s);
void Print(const IntStack* s);

먼저 stack.h 헤더파일을 따로 만들었다.

 

#include "stack.h"



int Initialize(IntStack* s, int max) {
    s->ptr = 0; //처음 주소값은 0, 스택이 비어있어야 하니까
    if ((s->stk = calloc(max, sizeof(int))) == NULL) {
        s->max = 0; // 접근할 수 있는 skt[0], skt[1] ,... , skt[max-1]
        return -1;
    }
    s->max = max;
    return 0;

};

/*--- 스택 pop 데이터를 제거하는 함수 ---*/
// 꼭대기에서 제거합니다
int Pop(IntStack* s, int* x) {
    if (s->ptr <= 0) // 스택이 비어있는 경우
        return -1;

    *x = s->stk[--s->ptr]; // 감소를 시키면서 가져와야 한다
    printf("Pop 값: %d\n", *x);
    return 0;
};


/*--- 스택 push 데이터를 추가하는 함수 ---*/
// 성공하면 0 반환, 실패하면 -1 반환

int Push(IntStack* s, int x) {
    if (s->ptr >= s->max) // 스택이 가득차 있는 상태
        return -1;
    
    printf("값을 입력하세요: ");
    scanf("%d", &x);
    s->stk[s->ptr++] = x;
    return 0;
};

/* --- 스택 peek 데이터를 제거하는 함수 ---*/
int Peek(IntStack* s, int* x) {
    if (s->ptr <= 0) // 스택이 비어있는가?
        printf("스택이 비어 있습니다.\n");
        return -1;
    *x = s->stk[s->ptr - 1];
    printf("스택의 꼭대기에 있는 요소: %d\n", s->stk[s->ptr - 1]);
    return 0;
};

/*--- 스택 clear 모든 데이터를 삭제하는 함수  ---*/
void Clear(IntStack* s) {
    s->ptr = 0;
    printf("스택이 비워졌습니다.\n");
};

/*--- 스택의 모든 요소를 시각적으로 출력하는 함수 ---*/
void Print(const IntStack* s) {
    printf("스택 상태: \n");
    for (int i = s->max - 1; i >= 0; i--) {
        if (i < s->ptr) {
            printf("| %d |\n", s->stk[i]);
        }
        else {
            printf("|   |\n"); // 비어 있는 슬롯을 표시
        }
    }
    printf("------\n");
}

소스파일 중에 스택의 기능만 가지고 있는 function.c 를 따로 만들었다

 

#include "stack.h"

// main.c 구현
int main(void) {
    IntStack s;
    if (Initialize(&s, 64) == -1) {
        printf("스택 생성에 실패했습니다.");
        return 1;
    }
    printf("1. push 2. pop 3. clear 4. 출력 5. 종료\n");
    while (1) {
        int menu, x=0;
        
        
        scanf("%d", &menu);
        if (menu == 1) {
            Push(&s, x);
            Print(&s);
            
        }
        else if (menu == 2) {
            Pop(&s, &x);
            Print(&s);
        }
        else if (menu == 3) {
            Clear(&s);
            Print(&s);
        }
        else if (menu == 4) {
            Peek(&s, &x);
            printf("현재 데이터 수: %d \n", s.ptr);
        }
        else if (menu == 5) {
            break;
        }


    }

    // Terminate(&s);
    free(s.stk);
    return 0;



}

마지막으로 main.c를 따로 나눠서 구현해줬다. 

 

 

스택구현1.mp4
0.09MB

 

스택구현2.mp4
0.15MB

아 동영상 잘 보이게 올려지는 줄 알았는데 아니었네..ㅜ

 

-4일차 끝-

 

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

자료구조+알고리즘 2일차  (0) 2023.07.29
자료구조+알고리즘 1일차  (0) 2023.07.27