본문 바로가기

자료구조

[자료구조] 리스트 - 03 . 환형 링크드 리스트 <구현>

[환형 링크드 리스트 구현]

=>헤더

#ifndef CDLL
#define CDLL
#include<stdio.h>
#include<stdlib.h>

typedef struct TagNode
{
	int Data;
	TagNode* PrevNode;
	TagNode* NextNode;
}Node;
//생성
Node* CDLL_CreateNode(int _Data);
//소멸
void CDLL_DestroyNode(Node* Destroy);
//추가
void CDLL_AppendNode(Node** Head, Node* NewNode);
//삽입
void CDLL_InsertNode(Node* Current, Node* NewNode);
//출력
void CDLL_PrintNode(Node* Head);
//역출력
void CDLL_ReversePrintNode(Node* Head);
//삭제
void CDLL_DeleteNode(Node** Head,Node* Delete);
//탐색
Node* CDLL_GetNodeAt(Node* Head, int location);
//수 세기
int CDLL_GetListCount(Node* Head);

#endif // !CDLL

=>함수

#include "CDLL_Header.h"

//생성
Node* CDLL_CreateNode(int _Data)
{
	Node* NewNode = (Node*)malloc(sizeof(Node));
	NewNode->Data = _Data;
	NewNode->NextNode = NULL;
	NewNode->PrevNode = NULL;
	return NewNode;
}

//추가
void CDLL_AppendNode(Node** Head, Node* NewNode)
{
	if (*Head == NULL)
	{
		(*Head) = NewNode;
		(*Head)->PrevNode = (*Head);
		(*Head)->NextNode = (*Head);
	}
	else
	{
		Node* Tail = (*Head)->PrevNode;
		Tail->NextNode = NewNode;
		NewNode->PrevNode = Tail;
		(*Head)->PrevNode = NewNode;
		NewNode->NextNode = (*Head);
	}
}
//삽입
void CDLL_InsertNode(Node* Current, Node* NewNode)
{
	NewNode->NextNode = Current->NextNode;
	NewNode->PrevNode = Current;
	Current->NextNode->PrevNode = NewNode;
	Current->NextNode = NewNode;
	
}

//삭제
void CDLL_DestroyNode(Node* Destroy)
{
	free(Destroy);
}

////일반 출력
//void CDLL_PrintNode(Node* Node)
//{
//	printf("노드 출력 시작\n");
//	Node->PrevNode==N
//}

//출력
void CDLL_PrintNode(Node* Head)
{
	Node* Current = Head;
	
	printf("출력 시작\n");
	while (Current!=NULL)
	{
		printf("%d\n", Current->Data);
		Current = Current->NextNode;
		if (Current == Head)
			break;
	}
	printf("출력 끝\n\n");
}
//역출력
void CDLL_ReversePrintNode(Node* Head)
{
	Node* Tail = Head->PrevNode;
	Node* Current = Tail;
	printf("역출력 시작\n");
	while (Current != NULL)
	{
		printf("%d\n", Current->Data);
		Current = Current->PrevNode;
		if (Current == Tail)
			break;
	}
	printf("역출력 끝\n\n");
}

//제거
void CDLL_DeleteNode(Node**Head , Node* Delete)
{
	if ((*Head) == Delete)
	{
		(*Head)->NextNode->PrevNode = Delete->PrevNode;
		(*Head)->PrevNode->NextNode = Delete->NextNode;
		(*Head) = Delete->NextNode;
	}
	else
	{
		Delete->NextNode->PrevNode = Delete->PrevNode;
		Delete->PrevNode->NextNode = Delete->NextNode;
	}
		Delete->NextNode = NULL;
		Delete->PrevNode = NULL;		
};

//탐색
Node* CDLL_GetNodeAt(Node* Head, int location)
{
	Node* Current = Head;
	while (--location > 0)
	{
		Current = Current->NextNode;
		if (Current == Head)
		{
			printf("범위를 벗어난 인덱스");
			return NULL;
		}
	}
	return Current;
}

//수 세기
int CDLL_GetListCount(Node* Head)
{
	int tempCount = 0;
	Node* Current = Head;
	while (Current != NULL)
	{
		tempCount++;
		Current=Current->NextNode;
		if (Current == Head)
		break;
	}
	printf("리스트의 개수는 %d\n\n", tempCount);
	return tempCount;
}

=>테스트

#include "CDLL_Header.h"

Node* List = NULL;

int main(void)
{

//출력
//역출력
//탐색
//수 세기

	//생성과 추가
	Node* Current = NULL;
	for (int i = 0; i < 5; i++)
	{
		CDLL_AppendNode(&List, CDLL_CreateNode(i));
	}
	CDLL_PrintNode(List);

	//노드 탐색후 삭제
	Node* tempNode = CDLL_GetNodeAt(List,3);
	CDLL_DeleteNode(&List, tempNode);
	CDLL_DestroyNode(tempNode);

	//노드 탐색후 삽입
	tempNode = CDLL_GetNodeAt(List, 2);
	CDLL_InsertNode(tempNode, CDLL_CreateNode(100));

	//노드 수 
	CDLL_GetListCount(List);

	//출력
	CDLL_PrintNode(List);

	//역출력
	CDLL_ReversePrintNode(List);

	//두번 출력하여 환형 리스트임을 확인한다.
	for (int i = 0; i < 10; i++)
	{
		if (i == 0)
			Current = List;
		else
			Current = Current->NextNode;
		printf("List[%d] : %d\n", i, Current->Data);
	}
}