JINTBEAT Design Life

C언어로 구현한 배열 기반 리스트(ArrayList) 구조와 함수 분석 - ArrayList.c 본문

🖥️ - Data Structure

C언어로 구현한 배열 기반 리스트(ArrayList) 구조와 함수 분석 - ArrayList.c

jintbeat_design 2025. 6. 6. 18:19
반응형
ArrayList.c
  • 함수의 실제 구현이 들어가 있다.
  • 헤더파일을 #include 해서 선언과 일치하도록 맞춰야 한다.
  • 사용자 입장에서는 내부 구현을 잘 몰라도 되는 것이다.

 

우선 전체 Source Code는 다음과 같다.

#include <stdio.h>
#include "ArrayList.h"

void ListInit(List *plist) {
	(plist->numOfData) = 0;
	(plist->curPosition) = -1;
}

void LInsert(List *plist, LData data) {
	if(plist->numOfData >= LIST_LEN) {
		printf("저장이 불가능합니다.\n");
		return;
	}

	plist->arr[plist->numOfData] = data;
	(plist->numOfData)++;
}


int LFirst(List *plist, LData *pdata) {
	if(plist->numOfData == 0)
		return FALSE;

	(plist->curPosition) = 0;
	*pdata = plist->arr[plist->curPosition];
	return TRUE;
}

int LNext(List *plist, LData *pdata) {
	if(plist->curPosition >= plist->numOfData-1)
		return FALSE;
	
	(plist->curPosition)++;	
	*pdata = plist->arr[plist->curPosition];
	return TRUE;
}

LData LRemove(List *plist) {
	int rpos = plist->curPosition;
	int num = plist->numOfData;
	int i;
	LData rdata = plist->arr[rpos];

	for(i = rpos; i < num-1; i++) {
		plist->arr[i] = plist->arr[i+1];
	}
	(plist->curPosition)--;
	(plist->numOfData)--;

	return rdata;
}

int LCount(List *plist) {
	return plist->numOfData;
}

 

void ListInit(List *plist)
void ListInit(List *plist) {
	(plist->numOfData) = 0;
	(plist->curPosition) = -1;
}
  • 리스트를 초기화
  • 요소 수는 0으로, 커서는 -1로 설정한다.
  • (plist->...) 괄호는 없어도 되지만, 가독성을 위해 쓴 것 같다.
  • -1로 초기화하는 이유는, 아직 데이터의 참조가 진행되지 않았음을 알려주는 의미이다.(그래서 0으로 초기화 안함)

 

void LInsert(List *plist, LData data)
void LInsert(List *plist, LData data) {
    if(plist->numOfData >= LIST_LEN) {
        printf("저장이 불가능합니다.\n"); // 리스트가 가득 찼을 때 메시지 출력
        return;
    }

    plist->arr[plist->numOfData] = data; // 데이터 삽입
    (plist->numOfData)++; // 데이터 수 증가
}
  • 리스트에 새 데이터를 마지막 위치에 삽입한다.
  • 최대 크기를 초과하면 경고 메시지를 출력하고 삽입을 하지 않는다.
  • 삽입 후 numOfData 증가

 

int LFirst (List *plist, LData *pdata)
int LFirst(List *plist, LData *pdata) {
	if(plist->numOfData == 0)
		return FALSE;

	(plist->curPosition) = 0;
	*pdata = plist->arr[plist->curPosition];
	return TRUE;
}
  • 리스트 순회 시작용 함수이다.
  • 첫 번째 데이터를 *pdata에 전달하고 TRUE 반환
  • 리스트가 비어있으면 FALSE 반환
int LNext (List *plist, LData *pdata)
int LNext(List *plist, LData *pdata) {
	if(plist->curPosition >= plist->numOfData-1)
		return FALSE;
	
	(plist->curPosition)++;	
	*pdata = plist->arr[plist->curPosition];
	return TRUE;
}
  • LFirst 다음에 호출해 다음 데이터를 순회할 때 사용
  • 다음 요소가 없으면 FALSE, 있으면 그 값을 *pdata에 전달

 

LData LRemove (List *plist)
LData LRemove(List *plist) {
	int rpos = plist->curPosition;
	int num = plist->numOfData;
	int i;
	LData rdata = plist->arr[rpos];

	for(i = rpos; i < num-1; i++) {
		plist->arr[i] = plist->arr[i+1];
	}
	(plist->curPosition)--;
	(plist->numOfData)--;

	return rdata;
}
  • 현재 커서 위치(curPosition)의 데이터를 삭제
  • 삭제된 이후 뒤의 데이터를 앞으로 한 칸씩 당김 (shift)
  • 리스트 크기 감소 및 커서도 한 칸 이전으로 조정
  • 삭제된 데이터를 반환

LRemove 함수 설명

 

int LCount (List *plist)
int LCount(List *plist) {
	return plist->numOfData;
}
  • 현재 리스트에 저장된 데이터 개수 반환

 

이 구조의 장점

 

항목 설명
구조적 리스트 배열 기반 리스트의 기초적 형태를 제공
커서 기반 순회 LFirst, LNext로 외부에서 반복 순회를 간편하게 구현 가능
삭제 후 정렬 삭제 후 데이터 재정렬로 배열 유지
캡슐화 구조체 내부 상태(arr, numOfData, curPosition)를 함수로만 접근하게 설계됨

 

반응형