반응형
연결기반 리스트
구현해보기
#ifdef _MSC_YER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include <stdlib.h>
typedef struct _node
{
int data;
struct _node* next;
} Node;
int main(void)
{
Node* head = NULL;
Node* tail = NULL;
Node* cur = NULL;
Node* newNode = NULL;
int readData;
//데이터 입력
while (1)
{
printf("자연수 입력: ");
scanf("%d", &readData);
if (readData < 1)
break;
//코딩...
}
printf("\n");
// 데이터 출력
printf("입력받은 데이터 전체 출력!\n");
if (head == NULL)
{
printf("저장된 자연수가 존재하지 않습니다.");
}
else
{
// 코딩...
}
printf("\n\n");
// 메모리 해제
if (head == NULL)
{
return 0; // 해제할 노드가 존재하지 않는다.
}
else
{
// 코딩...
}
return 0;
}
구현
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include <stdlib.h>
typedef struct _node
{
int data;
struct _node* next;
} Node;
int main(void)
{
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("저장된 자연수가 존재하지 않습니다.");
}
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;
}
연결 리스트의 ADT
리스트의 ADT와 똑같다 다만 SetSortRule이 추가 되었다.
* void ListInit(List * plist);
- 초기화할 리스트의 주소 값을인자로 전달한다.
- 리스트 생성 후 제일 먼저 호출되어야 하는 함수이다.
* void LInsert(List * plist, LData data);
- 리스트에 데이터를 저장한다. 매개변수 data에 전달된 값을 저장한다.
* int LFirst(List * plist, LData * pdata);
- 첫 번째 데이터가 pdata가 가리키는 메모리에 저장된다.
- 데이터의 참조를 위한 초기화가 진행된다.
- 참조 성공 시 TRUE(1), 실패 시 FALSE(0) 반환
* int LNext(List * plist, LData * pdata);
- 참조된 데이터의 다음 데이터가 pdata가 가리키는 메모리에 저장된다.
- 순차적인 참조를 위해서 반복 호출이 가능하다.
- 참조를 새로 시작하려면 먼저 LFirst 함수를 호출해야 한다.
- 참조 성공 시 TRUE(1), 실패 시 FALSE(0) 반환
* LData LRemove(List * plist);
- LFirst 또는 LNext 함수의 마지막 반환 데이터를 삭제한다.
- 삭제된 데이터는 반환된다.
- 마지막 반환 데이터를 삭제하므로 연이은 반복 호출을 허용하지 않는다.
* int LCount(List * plist);
- 리스트에 저장되어 있는 데이터의 수를 반환한다.
// new
* void SetSortRule(List* plist, int (*comp)(LData d1, LData d2));
- 리스트에 정렬의 기준이 되는 함수를 등록한다.
Main.c
#include <stdio.h>
#include "DLinkedList.h"
int main(void)
{
// 리스트의 생성 및 초기화
List list;
int data;
ListInit(&list);
// 5개의 데이터 저장
LInsert(&list, 11); LInsert(&list, 11);
LInsert(&list, 22); LInsert(&list, 22);
LInsert(&list, 33);
// 저장된 데이터의 전체 출력
printf("현재 데이터의 수: %d \n", LCount(&list));
if (LFirst(&list, &data))
{
printf("%d ", data);
while (LNext(&list, &data))
printf("%d ", data);
}
printf("\n\n");
// 숫자 22을 검색하여 모두 삭제
if (LFirst(&list, &data))
{
if (data == 22)
LRemove(&list);
while (LNext(&list, &data))
{
if (data == 22)
LRemove(&list);
}
}
// 삭제 후 남아있는 데이터 전체 출력
printf("현재 데이터의 수: %d \n", LCount(&list));
if (LFirst(&list, &data))
{
printf("%d ", data);
while (LNext(&list, &data))
printf("%d ", data);
}
printf("\n\n");
return 0;
}
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);
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 d2));
#endif
DLinkedList.c
구현해보기
#include <stdio.h>
#include <stdlib.h>
#include "DLinkedList.h"
void ListInit(List* plist)
{
}
void FInsert(List* plist, LData data)
{
}
void SInsert(List* plist, LData data)
{
// 아직 구현하지 마시오.
}
void LInsert(List* plist, LData data)
{
}
int LFirst(List* plist, LData* pdata)
{
return -1;
}
int LNext(List* plist, LData* pdata)
{
return -1;
}
LData LRemove(List* plist)
{
return -1;
}
int LCount(List* plist)
{
return -1;
}
void SetSortRule(List* plist, int (*comp)(LData d1, LData d2))
{
// 아직 구현하지 마시오.
}
구현
#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 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)
{
// 아직 구현하지 마시오.
}
void LInsert(List* plist, LData data)
{
if (plist->comp == NULL)
FInsert(plist, data);
else
SInsert(plist, data);
}
int LFirst(List* plist, LData* pdata)
{
if (plist->head->next == NULL)
return FALSE;
plist->before = plist->head;
plist->cur = plist->head->next;
*pdata = plist->cur->data;
return TRUE;
}
int LNext(List* plist, LData* pdata)
{
if (plist->cur->next == NULL)
return FALSE;
plist->before = plist->cur;
plist->cur = plist->cur->next;
*pdata = plist->cur->data;
return TRUE;
}
LData LRemove(List* plist)
{
Node* rpos = plist->cur;
LData rdata = rpos->data;
plist->before->next = plist->cur->next;
plist->cur = plist->before;
free(rpos);
(plist->numOfData)--;
return rdata;
}
int LCount(List* plist)
{
return plist->numOfData;
}
void SetSortRule(List* plist, int (*comp)(LData d1, LData d2))
{
// 아직 구현하지 마시오.
}
나머지기능구현
Main.c
#include <stdio.h>
#include "DLinkedList.h"
//new
int WhoIsPrecede(int d1, int d2)
{
if (d1 < d2)
return 0; // d1이 정렬 순서상 앞선다.
else
return 1; // d2가 정렬 순서상 앞서거나 같다.
}
int main(void)
{
// 리스트의 생성 및 초기화
List list;
int data;
ListInit(&list);
//new
SetSortRule(&list, WhoIsPrecede); // 정렬의 기준을 등록한다!
// 5개의 데이터 저장
LInsert(&list, 11); LInsert(&list, 11);
LInsert(&list, 22); LInsert(&list, 22);
LInsert(&list, 33);
// 저장된 데이터의 전체 출력
printf("현재 데이터의 수: %d \n", LCount(&list));
if (LFirst(&list, &data))
{
printf("%d ", data);
while (LNext(&list, &data))
printf("%d ", data);
}
printf("\n\n");
// 숫자 22을 검색하여 모두 삭제
if (LFirst(&list, &data))
{
if (data == 22)
LRemove(&list);
while (LNext(&list, &data))
{
if (data == 22)
LRemove(&list);
}
}
// 삭제 후 남아있는 데이터 전체 출력
printf("현재 데이터의 수: %d \n", LCount(&list));
if (LFirst(&list, &data))
{
printf("%d ", data);
while (LNext(&list, &data))
printf("%d ", data);
}
printf("\n\n");
return 0;
}
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);
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 d2));
#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 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)
{ //new
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)++; // 저장된 데이터의 수 하나 증가
}
void LInsert(List* plist, LData data)
{
if (plist->comp == NULL)
FInsert(plist, data);
else
SInsert(plist, data);
}
int LFirst(List* plist, LData* pdata)
{
if (plist->head->next == NULL)
return FALSE;
plist->before = plist->head;
plist->cur = plist->head->next;
*pdata = plist->cur->data;
return TRUE;
}
int LNext(List* plist, LData* pdata)
{
if (plist->cur->next == NULL)
return FALSE;
plist->before = plist->cur;
plist->cur = plist->cur->next;
*pdata = plist->cur->data;
return TRUE;
}
LData LRemove(List* plist)
{
Node* rpos = plist->cur;
LData rdata = rpos->data;
plist->before->next = plist->cur->next;
plist->cur = plist->before;
free(rpos);
(plist->numOfData)--;
return rdata;
}
int LCount(List* plist)
{
return plist->numOfData;
}
void SetSortRule(List* plist, int (*comp)(LData d1, LData d2))
{ //new
plist->comp = comp;
}
반응형