미연시리뷰

더블링크드리스트 보관용

두원공대88학번뚜뚜 2020. 8. 8. 23:50

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

int main(void) {
//리스트 생성 및 초기화//
List list;
int data;
ListInit(&list); //list의 주소값(=&list)을, plist형으로 전달.
 //*plist=&list. 즉 plist=list의 포인터변수

//5개 데이터 저장
LInsert(&list, 11); LInsert(&list, 22);
LInsert(&list, 33); LInsert(&list, 44);
LInsert(&list, 55);

//저장된 데이터 전체 출력
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));
{
printf("%d", data);

while (LNext(&list, &data))
printf("%d", data);
}
printf("\n\n");
return 0;
}

///////////////

#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;     //초기화 시, 메모리 할당 후 next와 정렬기준은 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) {
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; //다음 노드로 이동, 새 데이터가 저장될 위치를 찾아, pred위치가 고정될 시 , 연결함
}
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;  //더미노드가 NULL 가리킬 시엔, 반환할 데이터가 없음

plist->before = plist->head; //before을, 더미노드를 가리키게 한 다음
plist->cur = plist->head->next;    //cur은 첫 번째 노드를 가리키게 함

*pdata = plist->cur->data;
return TRUE;            //첫 번째 노드의 데이터 전달 후, 데이터 반환
}

int LNext(List *plist, LData *pdata) { //*pdata로 접근=해당 데이터를 직접 이용(삭제 혹은 탐색), 즉 주소값이 필요 / data로 접근=해당 데이터를 삽입. 주소값 불필요
if (plist->cur->next == NULL)
return FALSE;

plist->before = plist->cur; //before이 현 노드를 가리키게 한 다음
plist->cur = plist->cur->next;  //현 노드는, 현 노드의 다음을 가리키게 함

*pdata = plist->cur->data;
return TRUE;
}

LData LRemove(List *plist) { //Ldata형을 반환할 예정이니, 이렇게 삽입
Node * rpos = plist->cur;  //소멸대상의 주소값(cur)을, rppos에 저장. 즉, Node rpos=&(plist->cur)
LData rdata = rpos->data;

plist->before->next = plist->cur->next;  //소멸대상을 리스트에서 제거
plist->cur = plist->before;  //그 cur의 위치를 재조정

free(rpos);
(plist->numOfData)--;
return rdata;
}

//setsrotrule 함수가 호출되면서, 정렬의 기준이 리스트의 멤버 comp에 등록되면,
//sinsert함수 내에서는 comp에 등록된 정렬의 기준을 근거로 데이터를 정렬, 저장한다.

void SetSortRule(List *plist, int(*comp)(LData d1, LData d2)) {
plist->comp = comp;   //리스트의 멤버, comp를 초기화 하는 함수. 여기서 comp는 정렬의 기준
}

////////////////////

#ifndef __D_LINKED_LIST_H__
#define __D_LINKED_LIST_H__

#define TRUE 1
#define FALSE 0

typedef int LData; //typedef a b = a를 b로 재정의

typedef struct _node {
LData data;   //int data.
struct _node* next;   // 다음 노드를 가리키는 포인터의 선언
     // struct _node의 포인터 'next'의 선언, 즉 next는 struct _node의 주소
}Node;

typedef struct _linkedlist {
Node * head;
Node * cur;
Node * before;  // head는 각각 Node의 주소를 가리킨다.
int numOfData; 
int(*comp) (LData k1, LData d2);  //반환형이 int인 LData형 인자를 2개 전달받는
                                  //함수의 주소값 전달. 
} LinkedList;

typedef LinkedList List;

void ListInit(List *plist);
void LInsert(List *pklist, 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