배열을 이용한 데이터 저장 예제
코드 구현
#include <stdio.h>
int main() {
int arr[10];
int readCount = 0;
int readData;
int i;
while(1)
{
printf("자연수 입력: ");
scanf("%d", &readData);
if(readData < 1)
break;
arr[readCount++] = readData;
}
for(i=0; i<readCount; i++)
printf("%d ", arr[i]);
return 0;
}
결과 출력
자연수 입력: 1
자연수 입력: 2
자연수 입력: 3
자연수 입력: 4
자연수 입력: 5
자연수 입력: 6
자연수 입력: 0
1 2 3 4 5 6
배열은 메모리의 특성이 정적이어서 메모리의 길이를 변경하는 것이 불가
다음 예제를 통해 동적 메모리 구성을 파악
코드 구현
#include <stdio.h>
#include <stdlib.h>
typedef struct _node
{
int data;
struct _node * next;
} Node;
int main() {
Node * head = NULL;
Node * tail = NULL;
Node * cur = NULL;
Node * newNode = NULL;
int readData;
while(1)
{
printf("자연수 입력: ");
scanf("%d", &readData);
if(readData < 1)
break;
// 노드의 추가과정
newNode = (Node*)malloc(sizeof(Node));
newNode->data = readData;
newNode->next = NULL;
if(head == NULL)
head = newNode;
else
tail->next = newNode;
tail = newNode;
}
printf("\n");
printf("입력받은 데이터의 전체출력\n");
if(head == NULL) {
printf("저장된 자연수가 존재하지 않습니다. \n");
} else {
cur = head;
printf("%d ", cur->data);
while(cur->next != NULL) {
cur = cur->next;
printf("%d ", cur->data);
}
}
printf("\n\n");
if(head == NULL)
return 0;
else {
Node * delNode = head;
Node * delNextNode = head->next;
printf("%d을 삭제\n", head->data);
free(delNode);
while(delNextNode != NULL)
{
delNode = delNextNode;
delNextNode = delNextNode->next;
printf("%d을 삭제합니다. \n", delNode->data);
free(delNode);
}
}
return 0;
}
결과 출력
자연수 입력: 2
자연수 입력: 4
자연수 입력: 6
자연수 입력: 8
자연수 입력: 0
입력받은 데이터의 전체출력
2 4 6 8
2을 삭제
4을 삭제합니다.
6을 삭제합니다.
8을 삭제합니다.
위의 코드는 연결리스트의 ADT를 정의하지 않았고 삽입, 삭제, 조회 기능이 별도 함수로 구분되어 있지 않은 예제.
묶인 것이 아래의 예제이다. (여러 파일 구성)
코드 구현
// DLinkedList.h
#ifndef __D_LINKED_LIST_H__
#define __D_LINKED_LIST_H__
#define TRUE 1
#define FALSE 0
typedef int LData;
typedef struct _node
{
LData data;
struct _node* next;
} Node;
typedef struct _linkedList
{
Node* head; // 연결 리스트의 머리를 가리키는 포인터 변수 -> 더미 노드를 가리키는 멤버
Node* cur; // 참조를 위한 포인터 변수 -> 참조 및 삭제를 돕는 변수
Node* before; // 삭제를 돕는 멤버
int numOfData; // 저장된 데이터의 수를 기록하기 위한 멤버
int (*comp)(LData d1, LData d2); // 정렬의 기준을 등록하기 위한 멤버
} LinkedList;
typedef LinkedList List;
void ListInit(List* plist);
void LInsert(List* plist, LData data);
void FInsert(List* plist, LData data);
void SInsert(List* plist, LData data);
int LFirst(List* plist, LData* pdata);
int LNext(List* plist, LData* pdata);
LData LRemove(List* plist);
int LCount(List* plist);
// 리스트 정렬에 기준이 되는 함수를 등록한다.
void SetSortRule(List* plist, int (*comp)(LData d1, LData dc2));
#endif
// DLinkedList.c
#include <stdio.h>
#include <stdlib.h>
#include "DLinkedList.h"
void ListInit(List* plist)
{
plist->head = (Node*)malloc(sizeof(Node)); // 더미 노드 생성
plist->head->next = NULL;
plist->comp = NULL;
plist->numOfData = 0;
}
void LInsert(List* plist, LData data)
{
if(plist->comp == NULL)
{
FInsert(plist, data);
}
else
{
SInsert(plist, data);
}
}
void FInsert(List* plist, LData data)
{
Node* newNode = (Node*)malloc(sizeof(Node)); // 새 노드 생성
newNode->data = data; // 새 노드에 데이터 저장
newNode->next = plist->head->next; // 새 노드가 다른 노드를 가리키게 함
plist->head->next = newNode; // 더미 노드가 새 노드를 가리키게 함
plist->numOfData++; // 저장된 노드의 수 증가
}
void SInsert(List* plist, LData data)
{
Node* newNode = (Node*)malloc(sizeof(Node)); // 새 노드 생성
Node* pred = plist->head; // pred는 더미 노드를 가리킴
newNode->data = data;
// 새 노드가 들어갈 위치를 찾기 위한 반복문!
while(pred->next != NULL && plist->comp(data, pred->next->data) != 0)
{
pred = pred->next; // 다음 노드로 이동
}
newNode->next = pred->next; // 새 노드의 오른쪽을 연결
pred->next = newNode; // 새 노드의 왼쪽을 연결
plist->numOfData ++; // 저장된 노드의 수 증가
}
int LFirst(List* plist, LData* pdata) {
if (plist->head->next == NULL) {
return FALSE;
}
plist->before = plist->head; // before는 더미 노드를 가리키게 함
plist->cur = plist->head->next; // cur은 첫 번째 노드를 가리키게 함
*pdata = plist->cur->data; // 첫 번째 노드의 데이터를 전달
return TRUE;
}
int LNext(List* plist, LData* pdata)
{
if(plist->cur->next == NULL)
{
return FALSE;
}
plist->before = plist->cur; // cur이 가리키던 것을 before가 가리킴
plist->cur = plist->cur->next; // cur은 그 다음 노드를 가리킴
*pdata = plist->cur->data; // cur이 기리키는 노드의 데이터 전달
return TRUE;
}
LData LRemove(List* plist)
{
Node* rpos = plist->cur; // 소멸 대상의 주소 값을 rpos에 저장
LData rdata = rpos->data; // 소멸 대상의 데이터를 rdata에 저장
plist->before->next = plist->cur->next; // 소멸 대상을 리스트에서 제거
plist->cur = plist->before; // cur이 가리키는 위치를 재조정
free(rpos); // 리스트에서 제거된 노드 소멸
plist->numOfData --; // 저장된 데이터의 수 하나 감소
return rdata;
}
int LCount(List* plist)
{
return plist->numOfData;
}
void SetSortRule(List* plist, int(*comp)(LData d1, LData d2))
{
plist->comp = comp;
}
// DLinkedListMain.c
#include <stdio.h>
#include "DLinkedList.h"
int whoIsPrecede(int d1, int d2)
{
if(d1 < d2)
{
return 0;
}
return 1;
}
int main()
{
List list;
int data;
ListInit(&list);
SetSortRule(&list, whoIsPrecede);
// 5개의 데이터 저장
LInsert(&list, 1);
LInsert(&list, 2);
LInsert(&list, 3);
LInsert(&list, 4);
LInsert(&list, 5);
// 저장된 데이터의 전체 출력
printf("현재 데이터의 수: %d \n", LCount(&list));
if(LFirst(&list, &data))
{
printf("%d ", data);
while(LNext(&list, &data))
{
printf("%d ", data);
}
}
// 숫자 2를 검색하여 모두 삭제
printf("현재 데이터의 수: %d \n", LCount(&list));
if(LFirst(&list, &data))
{
if(data == 2)
{
LRemove(&list);
}
while(LNext(&list, &data))
{
if(data == 2)
{
LRemove(&list);
}
}
}
printf("현재 데이터의 수: %d \n", LCount(&list));
if(LFirst(&list, &data))
{
printf("%d ", data);
while(LNext(&list, &data))
{
printf("%d ", data);
}
}
}
댓글 없음:
댓글 쓰기