https://www.acmicpc.net/problem/10808

 

10808번: 알파벳 개수

단어에 포함되어 있는 a의 개수, b의 개수, …, z의 개수를 공백으로 구분해서 출력한다.

www.acmicpc.net

 

#코드

#include <bits/stdc++.h>
using namespace std;

int alph[26];

int    main(void)
{
    string s;
    cin >> s;
    for (auto c : s)
        alph[c - 'a']++;
    for (auto n : alph)
        cout << n << ' ';
}

 

#설명

알파벳을 저장할 배열을 전역에 선언합니다. (배열을 전역에 선언하면 배열의 원소들이 자동으로 0으로 초기화됩니다.)

알파벳 소문자 a ~ z 까지 총 26개를 저장하기 위해 크기는 26으로 선언했습니다.

 

for문에서 string (char 타입 배열)의 원소들, 즉 알파벳에 하나씩 접근하면서 

알파벳의 순서에 해당하는 인덱스의 값을 증가시켜줍니다. 

( 알파벳 소문자는 아스키코드 상에서 97 ~ 122이기 때문에 97(='a')을 빼서 0 ~ 26 사이의 숫자로 바꿔주었습니다. )

 

그리고 나서 배열 alpha의 원소들을 공백으로 구분해 하나씩 출력해주면 됩니다. 

 

 

 

https://www.acmicpc.net/problem/4949

 

4949번: 균형잡힌 세상

문제 세계는 균형이 잘 잡혀있어야 한다. 양과 음, 빛과 어둠 그리고 왼쪽 괄호와 오른쪽 괄호처럼 말이다. 정민이의 임무는 어떤 문자열이 주어졌을 때, 괄호들의 균형이 잘 맞춰져 있는지 판단

www.acmicpc.net

#include <iostream>
#include <string>
#include <stack>
#include <istream>
using namespace std;

stack<char> stck;

void	print_result(int is_balanced)
{
	if (is_balanced)
		cout << "yes\n";
	else
		cout << "no\n";
}

int		find_match(char c)
{
	if (stck.empty())
		return (0);
	if ((c == ')' && stck.top() == '(') ||
		(c == ']' && stck.top() == '['))
	{
		stck.pop();
		return (1);
	}
	return (0);
}

int		main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);

	int flag;

	while (1)
	{
		string s;
		flag = 1;
		while (!stck.empty()) stck.pop();
		getline(cin, s);
		if (s == ".")
			break ;
		for (auto c : s)
		{
			if (c == '(' || c == '[')
				stck.push(c);
			else if (c == ')' || c == ']')
			{
				if (!find_match(c))
				{
					flag = 0;
					break ;
				}
			}
		}
		if (stck.empty() && flag)
			print_result(1);
		else
			print_result(0);
	}
}

 

문제 풀 때 참고한 글

https://twpower.github.io/75-how-to-use-stack-in-cpp

 

[C++] C++ STL stack 기본 사용법과 예제

Practice makes perfect!

twpower.github.io

 

 

https://www.acmicpc.net/problem/10828

 

10828번: 스택

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 �

www.acmicpc.net

 

#include <iostream>
#include <algorithm>
using namespace std;

int	stac[10001];
int	pos = 0;

void		print_is_empty()
{
	if (pos == 0)
		cout << 1 << '\n';
	else
		cout << 0 << '\n';
}

void		print_top()
{
	int top;

	if (pos == 0)
		cout << -1 << '\n';
	else
		cout << stac[pos - 1] << '\n';
}

void		push(int X)
{
	stac[pos] = X;
	pos++;
}

void		pop()
{
	if (pos == 0)
		cout << -1 << '\n';
	else
	{
		cout << stac[pos - 1] << '\n';
		pos--;
	}
}

void		print_size()
{
	cout << pos << '\n';
}

void		check_order(string order)
{
	if (order == "pop")
		pop();
	else if (order == "size")
		print_size();
	else if (order == "empty")
		print_is_empty();
	else
		print_top();
}

int			main(void)
{
	int		N;
	int		X;
	string	order = "";

	cin >> N;
	for (int i = 0; i < N; i++)
	{
		cin >> order;
		if (order == "push")
		{
			cin >> X;
			push(X);
		}
		else
			check_order(order);
	}
	return (0);
}

 

 

https://javascript30.com/

 

JavaScript 30

Build 30 things with vanilla JS in 30 days with 30 tutorials

javascript30.com

 

라이브러리나 프레임워크 사용 없이 모던자바스크립트만으로 하루에 하나씩 30일 동안 30가지 미니 프로젝트를 만들어보는 챌린지입니다

이메일만 등록하면 무료로 참여할 수 있고 동영상 튜토리얼 30개와 스타터파일이 제공돼요

동영상은 영어지만 (영어)자막이 있어서 이해하기가 아주 어렵지는 않아요

 

개발을 잘하려면 프로젝트를 경험을 많이 쌓는 게 중요하다고 하는데

프로젝트 아이디어를 직접 떠올리고 무에서 유를 창조해내는(?) 게 부담스러운 분들은

이렇게 주제와 디자인이 정해진(+튜토리얼까지 제공되는) 미니 프로젝트를 따라 만들어보는 것으로 먼저 시작해보는 것도 좋을 것 같습니다. 

 

사이트에 들어가면 다음과 같은 화면이 뜹니다

 

이메일을 입력하고 Join을 누른다음 간단한 이메일 인증절차를 거치면 바로 시작할 수 있어요

 

이메일을 등록하고 메인화면 오른쪽 위에 있는 'my account' 버튼을 눌러서 들어가면 

이렇게 My Course 화면이 뜹니다. 

여기에서 Stream Course를 누르면 바로 동영상 튜토리얼을 볼 수 있어요

참고로 동영상 튜토리얼은 유튜브에도 올라와있어요. Javascript30 이라고 검색하면 바로 나오더라구요

튜토리얼을 시작하기 전에 먼저 Starter Files로 들어가서 깃허브링크에서 파일을 다운로드 해야합니다

(슬랙 채널은 유료 사용자들만 이용할 수 있다는 것 같네요)

 

깃허브 링크를 타고 들어가면

이렇게 챌린지별로 폴더가 있습니다. 

 

첫번째 챌린지 폴더 안을 보면 html과 css파일, 그 외에 필요한 자료들이 있습니다. 

파일 이름만 봐도 아시겠지만 index-FINISHED.html 파일은 완성본이고

우리는 index-START.html 파일에 직접 코드를 작성해서 완성본처럼 동작하게 해야합니다. 

 

완성본을 먼저 확인해보고 어떻게 구현해야할지 생각해본 뒤, 튜토리얼을 참고하면서 만들어나가면 될 것 같네요 

 

저도 오늘부터 시작하고 진행하면서 틈틈이 후기를 올릴 예정입니다 !! 

 

https://geonlee.tistory.com/48

 

[JavaScript] 🎹 JavaScript로 악기 만들기

🎹 Day 1 - JavaScript로 악기 만들기 JavaScript 30의 첫 번째 프로젝트는 '드럼 킷 만들기'이다. 특정 키보드 버튼을 누르면 해당하는 드럼 소리가 나와서 연주를 할 수 있는 프로젝트이다. 😃 HTML 코드

geonlee.tistory.com

https://takeuu.tistory.com/37?category=733951

 

1. JavaScript Drum Kit

JavaScript Drum Kit 위에 첨부한 사진처럼 해당하는 키보드를 누르면 화면에 효과와 함께 소리가 나는 드럼 킷을 만드는 것 기본 코드

takeuu.tistory.com

다른 블로거 분들이 구현코드까지 올려주신 상세한 후기가 있길래 링크 올립니다. 언어의 장벽이 있거나 막히는 부분이 있을 때 참고하시면 좋을 것 같아요

문제 링크

https://www.acmicpc.net/problem/2577

 

2577번: 숫자의 개수

첫째 줄에 A, 둘째 줄에 B, 셋째 줄에 C가 주어진다. A, B, C는 모두 100보다 같거나 크고, 1,000보다 작은 자연수이다.

www.acmicpc.net

 

풀이

#include <stdio.h>

int main() {
    int a, b, c;
    int arr[10] = {0, };
    scanf("%d %d %d", &a, &b, &c);
    int n = a*b*c;
    
    int num;
    while(n>0) {
        num = n%10;
        arr[num]++;
        n /= 10;
    }
    
    for(int i=0; i<10; i++) {
        printf("%d\n", arr[i]);
    }
    
    return 0;
}

정수를 자릿수에 따라 쪼개야할 때는 10으로 나눗셈/나머지연산을 하면 간단하게 처리할 수 있다.

배열 arr은 while문에서 값을 새로 할당하는 것이 아니라 원래 값을 증가시키기 때문에(증감 연산자 사용)

선언할 때 0으로 초기화를 해두어야한다. 

 

배열 0으로 초기화하기 : https://dojang.io/mod/page/view.php?id=294

(C언어 코딩 도장 36.2 배열을 0으로 초기화하기)

 

문제 링크 : https://www.acmicpc.net/problem/1110

 

1110번: 더하기 사이클

0보다 크거나 같고, 99보다 작거나 같은 정수가 주어질 때 다음과 같은 연산을 할 수 있다. 먼저 주어진 수가 10보다 작다면 앞에 0을 붙여 두 자리 수로 만들고, 각 자리의 숫자를 더한다. 그 다음, 주어진 수의 가장 오른쪽 자리 수와 앞에서 구한 합의 가장 오른쪽 자리 수를 이어 붙이면 새로운 수를 만들 수 있다. 다음 예를 보자. 26부터 시작한다. 2+6 = 8이다. 새로운 수는 68이다. 6+8 = 14이다. 새로운 수는 84이다. 8+4 =

www.acmicpc.net

 

풀이

#include  

int main() { 
    int n; 
    int a, b, c; 
    int cycle = 0; 
    int comp; 
    c = -1; 
     
    scanf("%d", &n); 
    comp = n; 
     
    do { 
        a = n/10; 
        b = n%10; 
        c = a + b; 
        n = b*10 + c%10; 
        cycle++; 
    } while (n!=comp); 
     
    printf("%d", cycle); 
    return 0; 
}

그렇게 깔끔하진 못한 것 같다. 그래도 맞다고 나오기는 했다. 

 

숫자를 자릿수에 따라 쪼개려면 나눗셈과 나머지연산을 이용하면 된다. 

 

주어진 수가 26일 때, 

주어진 수를 10으로 나눠 10의 자리를 구하고 (26/10 = 2),

주어진 수를 10으로 나눴을 때의 나머지를 구해 1의 자리를 구하면 된다. (26%10 = 6)

 

주어진 수가 두 자리수가 아닐 때도 같은 방법으로 하면 된다.

주어진 수가 9라면, 

9/10 = 0

9%10 = 9 이므로 문제에서 요구하는 조건을 만족한다. 

(문제 : 주어진 수가 10보다 작다면 앞에 0을 붙여 두 자리 수로 만들고, 각 자리의 숫자를 더한다. )

 

 

 

※ 인프런 무료강좌 C로 배우는 자료구조(권오흠 교수님)를 보고 개인적인 복습을 위해 정리한 내용입니다.


삽입 정렬 (insert sort)

하나의 배열에 데이터들이 이미 정렬되어있을 때, 정렬을 유지하면서 새로운 데이터를 삽입하는 알고리즘이다.

새로운 데이터를 정렬된 배열의 앞에 있는 데이터부터 차례대로 비교하면서 자신의 위치를 찾아 삽입한다.

이러한 삽입 연산을 반복적으로 수행함으로써 데이터들을 정렬한다.

 

오름차순 삽입 정렬 코드 

void insertion_sort(int n, int data[]) {
	for (int i=1; i<n; i++) {
		int tmp = data[i];
		/* i-1 ~ 0까지 while문을 돌며 비교한다 */
		int j = i-1;
		while (j>=0 && data[j]>tmp) {
			/* tmp보다 큰 값들을 뒤로 한 칸씩 옮긴다. */
			data[j+1] = data[j];
			j-;
		}
		/* tmp보다 작은 값을 발견하면 그 바로 다음 자리에 tmp를 삽입한다 */
		data[j+1] = tmp;
	}
}

배열의 두번째 원소(1)부터 시작해 마지막 원소(n-1)까지 반복문을 돈다.

해당 원소를 앞에 있는 원소들(=정렬된 상태)과 비교해

적절한 위치에 삽입한다.

이렇게 data[0] ~ data[i-1] 중에 제자리를 찾아 data[i]를 삽입하는 일을 반복한다.

 

삽입정렬의 시간복잡도는 ?

최악의 경우는 데이터가 반대로 정렬되어있는 경우(내림차순으로 정렬되어있는 데이터를 오름차순으로 정렬하려고 할 때 등)이다.

이 경우 시간복잡도는 n(n-1)/2 ⇒ O(n^2)이다.

평균적으로는 절반 정도의 시간이 걸릴 것이다.

 

삽입 정렬은 버블 정렬보다 많이 쓰이는 정렬 알고리즘이다.

일반적인 경우에는 삽입 정렬이 버블 정렬보다 대략 두 배 정도 빠르기 때문이다.

 

 

그 외의 정렬 알고리즘

퀵 소트(quicksort) 알고리즘

시간복잡도 측면에서 조금 특이한 알고리즘이다.

최악의 경우에는 O(n^2)이지만, 평균 시간복잡도는 O(nlog②n)로

최악의 경우와 일반적인 경우에 효율성에 차이가 매우 크다.

최악의 경우를 제외하고 일반적으로는 나쁘지 않은 효율성을 가진 알고리즘이라고 볼 수 있다.

라이브러리 형태로도 많이 제공되므로 대부분의 경우에는 퀵 소트 알고리즘이 쓰인다.

 

합병정렬(merge sort), 힙 정렬(heap sort) 알고리즘

최악의 경우 O(nlog2n)의 시간복잡도를 가지는 정렬 알고리즘이다.

구현이 어렵지만 효율적이다.

 

+) 만약 데이터가 배열이 아닌 연결리스트에 저장되어 있다면?

어떤 경우에도 O(n^2)의 시간복잡도를 벗어나기 힘들다.

주로 삽입 정렬 알고리즘을 많이 사용한다.

※ 인프런 무료강좌 C로 배우는 자료구조(권오흠 교수님)를 보고 개인적인 복습을 위해 정리한 내용입니다.


버블 정렬

배열에서 서로 인접한 두 원소를 검사하여 큰 값을 뒤로 보낸다.

이것을 배열의 끝에 도달할 때까지 반복하면

인덱스 0 ~ n-1까지의 원소들 중에서 가장 큰 값(/작은 값)을 맨 뒤(n-1)로 보내게 된다.

(n-1은 다음 정렬에서 제외된다. 정렬이 수행될 때마다 제외되는 원소가 뒤에서부터 하나씩 늘어난다. )

같은 방법으로

0~ n-2까지의 원소들 중에서 가장 큰 값을 n-2로 보내기

(n-2가 정렬에서 제외됨)

0~ n-3까지의 원소들 중에서 가장 큰 값을 n-3으로 보내기

(n-3이 정렬에서 제외됨)

...

0~1까지의 원소들 중에서 큰 값을 1로 보내기

 

위와 같은 과정을 거쳐 오름차순 정렬을 할 수 있고

큰 값을 뒤로 보내는 대신 작은 값을 뒤로 보내면 내림차순 정렬을 할 수 있다.

 

오름차순 버블 정렬 코드

void bubbleSort(int data[], int n) {
	for (int i=n-1; i>0; i--) {
		for (int j=0; j<1; j++) {
			if (data[j] > data[j+1]) {
				int tmp = data[j];
				data[j] = data[j+1];
				data[j+1] = tmp;
			}
		}
	}
}

 

원소를 교환(SWAP)할 때는

tmp = data[j];

data[j] = data[j+1];

data[j+1] = tmp;

위와 같이 세 번의 치환 연산이 필요하다.

 

data[j] = data[j+1];

data[j+1] = data[j];

위와 같이 두 번 연산하면 원래 data[j]의 값이 사라지기 때문에 제대로 치환을 할 수 없다.

원래 data[j]의 값을 tmp에 저장한 후 tmp를 이용해 두 변수의 값을 교환해야 한다.

 

버블 정렬의 시간복잡도는 ?

O(n^2)

최악, 평균과 관계없이 모두 일정하다.

버블 정렬 알고리즘 자체는 구현이 매우 간단하지만, 데이터의 교환(SWAP)이 복잡하기 때문에 거의 쓰이지 않는다. (구현은 쉽지만 효율이 낮음)

 

※ 인프런 무료강좌 C로 배우는 자료구조(권오흠 교수님)를 보고 개인적인 복습을 위해 정리한 내용입니다.


 

환형 배열로 큐 구현하기

큐의 경우 배열보다는 연결리스트로 구현하는 것이 좀 더 간단한데, 

배열은 크기가 정해져있기 때문이다. 

 

환형 배열(Circular array)을 이용해 큐를 구현하면 배열의 끝에 도달할 때마다 재할당을 해서 크기를 늘리지 않아도 된다.

 

배열의 앞에서부터 순서대로 데이터들을 저장한다.

데이터를 삭제하게 되면, 먼저 저장한 데이터부터(앞에서부터) 지워나간다.

이렇게 해서 배열의 앞에는 공간이 있고, 배열의 끝에는 데이터가 저장되어있는 상태에서 새로운 원소를 또 추가한다면,

다시 배열의 첫번째 칸에서부터 추가한다.

 

이와 같이 원형으로 순환하며 데이터를 저장한다.

 


헤더 파일은 연결리스트 구현 때 만든 파일을 그대로 사용한다.

terminate() 함수와 get_size() 함수도 완전히 동일하다.

 

구조체 정의하기

queueADT.c

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

#define INIT_CAPACITY 100

struct queue_type {
	Item *contents; /* 배열 */
	int front;
	int rear;
	int size; /* 저장된 데이터의 개수 */
	int capacity; /* 배열 contents의 크기 */
};

 

함수 정의하기

create(), destroy()

Queue create()
{
	Queue q = (Queue)malloc(sizeof(struct queue_type));
	if (q == NULL)
		terminate("Error in create: queue could not be created.");

	q->contents = (Item *)malloc(INIT_CAPACITY * sizeof(Item));
	if (q->contents == NULL) {
		free(q);
		terminate("Error in create: queue could not be created.");
	}

	q->front = 0;
	q->rear = -1; /* */
	q->size = 0;
	q->capacity = INIT_CAPACITY;
	return q;
}


void destroy(Queue q)
{
	free(q->contents);
	free(q);
}

 

empty(), full()

void make_empty(Queue q)
{
	q->front = 0;
	q->rear = -1;
	q->size = 0;
	/* q->contents는 그대로 두고(제거X) 초기화만 시킨다 */
}

bool is_empty(Queue q)
{
	return q->size == 0;
}

bool is_full(Queue q)
{
	return q->size == q->capacity;
}

 

enqueue(), dequeue(), peek()

void enqueue(Queue q, Item i)
{
	if (is_full(q))
		reallocate(q);
	q->rear = (q->rear + 1)%(q->capacity); 
	/* if (q->rear +1) = capacity, q->rear = 0; */
	q->contents[q->rear] = i;
	q->size++;
}


Item dequeue(Queue q)
{
	if (is_empty(q))
		terminate("Error in dequeue: queue is empty.");
	Item result = q->contents[q->front];
	q->front = (q->front + 1)%(q->capacity); 
	/* 배열의 끝에 도달(q->front+1 == capacity)하면 다시 0으로 돌아감 */
	q->size--;
	return result;
}


Item peek(Queue q)
{
	if (is_empty(q))
		terminate("Error in peek: queue is empty.");
	return q->contents[q->front];
}

enqueue() 함수에서

q->rear = (q->rear + 1)%(q->capacity);

위 식의 결과는

만약 q->rear + 1capacity보다 작다면,

그대로 q->rear + 1 이 되어 마지막 원소 다음 자리에 Item을 삽입하게 된다.

만약 q->rear + 1 == capacity라면 결과는 0이 되어

배열의 첫번째 칸에 Item을 삽입하게 된다.

 

이렇게 하여 앞에서 언급한 것처럼 순환하는 배열(Circular array)을 만들 수 있다.

 

dequeue() 함수에서도 비슷한 식을 사용한다.

q->front = (q->front + 1)%(q->capacity);

dequeue() 함수에서는 front를 이동시키기 전에

front가 원래 가리키고 있던 데이터를 따로 저장해뒀다가 반환한다.

 

이렇게 코드를 작성하는 것이 간결하지 못하게 느껴진다면

또다른 방법이 있다.

 

front가 큐의 첫번째 데이터가 아닌 첫번째 데이터의 한칸 앞을 가리키도록 하고

그 상태에서

q->front = (q->front + 1)%(q->capacity);

front를 이동시킨 다음,

front가 가리키는 데이터를 반환하면 그것이 이동 전의 원래 데이터가 된다.

이렇게 하면 원래 데이터를 따로 저장해두는 과정을 생략할 수 있으므로 코드가 좀 더 간략해진다.

(front가 계속 한 칸 앞 데이터를 가리키기 때문)

 

reallocate()

void reallocate(Queue q)
{
	Item *tmp = (Item *)malloc(2 * q->capacity * sizeof(Item));
	if (tmp == NULL) {
		terminate("Error in create: queue could not be expanded.");
	}

	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;
}

 

※ 인프런 무료강좌 C로 배우는 자료구조(권오흠 교수님)를 보고 개인적인 복습을 위해 정리한 내용입니다.


단방향 연결리스트로 큐 구현하기

연결리스트의 맨 앞에서는 삽입과 삭제가 모두 어렵지 않다.

그러나 연결리스트의 맨 뒤에서는, 삽입은 괜찮지만 삭제를 하기가 어렵다.

단방향 연결리스트에서 어떤 노드를 삭제하기 위해서는 이전 노드의 주소를 알아야하기 때문이다.

따라서 연결리스트의 뒤쪽을 삽입이 일어나는 rear로,

앞쪽을 삭제가 일어나는 front로 하는 것이 유리하다.

삽입을 하기 위해서는 마지막 노드의 주소를 항상 기억해야 하므로,

연결리스트 포인터 구조체에 첫번째 노드의 주소를 저장하는 front변수(=head) 외에도 rear 변수를 따로 둬서 마지막 노드 주소를 저장하는 데 사용한다.

 

헤더파일 정의하기

queueADT.h

#ifndef QUEUEADT_H
#define QUEUEADT_H

#include <stdbool.h> /* C99 only */

typedef int Item;
typedef struct queue_type *Queue;

Queue create();
void destroy(Queue q);
void make_empty(Queue q);
bool is_empty(Queue q);
void enqueue(Queue q, Item i);
Item dequeue(Queue q);
Item peek(Queue q);
int get_size(Queue q);

#endif

스택을 구현할 때와 함수의 종류가 거의 비슷하지만,

큐에 현재까지 저장된 데이터의 수가 몇개인지 알아낼 수 있는 get_size()함수가 추가되었다.

 

구조체 정의하기

queueADT.c

#include <stido.h>
#include <stdlib.h>
#include "queueADT.h"

struct node {
	Item data;
	struct node *next;
};

struct queue_type {
	struct node *front;
	struct node *rear;
	int size;
};

 

함수 정의하기 1 - 기본 함수들

queueADT.c

void terminate(const char *message) /* 예외 처리 */
{
	printf("%s\n", message);
	exit(EXIT_FAILURE);
}

int get_size(Queue q)
{
	return q->size;
}

Queue create()
{
	Queue q = (Queue)malloc(sizeof(struct queue_type));
	if (q == NULL)
		terminate("Error in create: queue could not be created.");
	q->front = NULL;
	q->rear = NULL;
	q->size = 0;
	return q;
}

void destroy(Queue q)
{
	make_empty(q);
	free(q);
}

void make_empty(Queue q)
{
	while (!is_empty(q))
		dequeue(q);
	q->size = 0;
}

 

함수 정의하기 2 - enqueue() 함수

bool is_empty(Queue q)
{
	return q->front == NULL; 
	/* or return q->size == 0 */
}

void enqueue(Queue q, Item I)
{
	struct node *new_node = (struct node *)malloc(sizeof(struct node));
	if (new_node == NULL)
		terminate("Error in push: queue is full.");

	new_node->data = i;
	new_node->next = NULL;

	/* q가 비어있을 때 */
	if (q->front == NULL) {
		q->front = new_node;
		q->rear = new_node;
	}
	/* q에 하나 이상의 노드가 있을 때 */
	else {
		q->rear->next = new_node;
		q->rear = new_node;
	}
	q->size++;
}

 

함수 정의하기 3 - dequeue() 함수, peek() 함수

Item dequeue(Queue q)
{
	struct node *old_front;
	Item i;

	if (is_empty(q)) /* q가 비어있을 때 */
		terminate("Error in dequeue: queue is empty.");

	old_front = q->front;
	i = old_front->data;
	q->front = old_front->next;

	
	if (q->front == NULL) /* q에 하나의 노드만 있었을 때 */
		q->rear = NULL;
	
	free(old_front);
	q->size--;
	return i;
}


Item peek(Queue q)
{
	if (is_empty(q))
		terminate("Error in peek: queue is empty.");
	return q->front->data;
}

dequeue() 함수는 q의 front가 두번째 노드를 가리키도록 한다.

또한 첫번째 노드를 free시켜주고, 첫번째 노드에 담긴 데이터(Item)를 반환해주는 일도 한다.

+ Recent posts