C/Reference

[C] 이중 연결 리스트 (Double Linked List)

MoongStory 2024. 12. 18. 16:12
반응형

출처 - C로 배우는 알고리즘 (이재규 지음)

#include <stdio.h>
#include <stdlib.h>

typedef struct _node
{
	int key;
	struct _node *prev;
	struct _node *next;
}node;

void init_dlist(void);			// head와 tail 메모리 할당 및 next, prev 초기화
node *insert_node_ptr(int k, node *t);	// 매개변수 t노드의 앞에 매개변수 k를 key 값으로 가지는 노드를 추가
int delete_node_ptr(node *p);		// 매개변수 p노드를 삭제
node *find_node(int k);			// 매개변수 k를 key 값으로 가지는 노드 검색
int delete_node(int k);			// 매개변수 k를 key 값으로 가지는 노드를 삭제, 여러개일 경우 맨 앞의 노드만 삭제
node *insert_node(int t, int k);	// 매개변수 t를 key 값으로 가지는 노드가 있으면, 해당 노드 앞에 매개변수 k를 key 값으로 가지는 노드 추가
node *ordered_insert(int k);		// 오름차순으로 하여 매개변수 k를 key 값으로 가지는 노드 추가
void print_list(node *t);		// 매개변수로 넘겨준 노드부터 시작해서 끝까지 출력
node *delete_all();			// 모든 노드를 삭제(head와 tail은 삭제 안함, head->next가 tail을 가르키도록 초기화)

node *head, *tail;

int main(int argc, char *argv[], char **env)
{
	node *t = NULL;
	init_dlist();

	ordered_insert(10);
	ordered_insert(5);
	ordered_insert(8);
	ordered_insert(3);
	ordered_insert(1);
	ordered_insert(7);
	ordered_insert(8);

	// 제대로 정렬되서 들어갔는지 확인
	printf("Initial Linked list is\n");
	print_list(head->next);

	// 4를 키값으로 가지는 노드 검색
	printf("Finding 4 is %ssuccessful\n", find_node(4) == tail ? "un" : "");
	puts("");

	// 5를 키값으로 가지는 노드 검색
	t = find_node(5);
	printf("Finding 5 is %ssuccessful\n", t == tail ? "un" : "");
	puts("");

	// 5 다음에 7을 추가
	printf("Inserting 7 before 5\n");
	insert_node_ptr(7, t);
	print_list(head->next);

	// 3을 key 값으로 가지는 노드를 찾아 삭제
	t = find_node(3);
	printf("Deleting Node having key Value 3\n");
	delete_node_ptr(t);
	print_list(head->next);

	// 키값이 10인 노드를 찾아 그 노드 앞에 키값으로 2를 가지는 노드 추가
	printf("Insert node 2 before 10\n");
	insert_node(10, 2);
	print_list(head->next);

	// 키값이 2인 노드를 찾아서 삭제
	printf("Deleting node 2\n");
	if(!delete_node(2))
	{
		printf("deleting 2 is unsuccessful");
	}
	print_list(head->next);

	// 키값이 11인 노드를 찾아서 삭제
	printf("Deleting node 1\n");
	if(!delete_node(1))
	{
		printf("deleting 11 is unsuccessful\n");
	}
	print_list(head->next);

	printf("Inserting 15 at first\n");
	insert_node_ptr(15, head->next);
	print_list(head->next);

	// 모든 노드 삭제
	printf("Deleting all node\n");
	delete_all();
	print_list(head->next);

	return 0;
}

void init_dlist(void)
{
	head = (node *)calloc(sizeof(node), 1); // head 노드 메모리 할당
	tail = (node *)calloc(sizeof(node), 1); // tail 노드 메모리 할당
	head->next = tail; // haed가 가리키는 다음 노드는 tail
	head->prev = head; // head가 가리키는 이전 노드는 자기자신
	tail->next = tail; // tail이 가리키는 다음 노드는 자기자신
	tail->prev = head; // tail이 가리키는 이전 노드는 head
}

node *insert_node_ptr(int k, node *t)
{
	node *new_node = NULL;

	if(t == head) // head 앞에는 노드 추가 불가능
	{
		return NULL;
	}

	new_node = (node *)calloc(sizeof(node), 1);
	new_node->key = k;

	t->prev->next = new_node;
	new_node->prev = t->prev;
	t->prev = new_node;
	new_node->next = t;

	return new_node;
}

int delete_node_ptr(node *p)
{
	if(p == head || p == tail)
	{
		return 0;
	}

	p->prev->next = p->next;
	p->next->prev = p->prev;

	free(p);

	return 1;
}

// 찾는 값이 없을 경우 tail 리턴
node *find_node(int k)
{
	node *s = NULL;

	s = head->next;

	while(s->key != k && s != tail)
	{
		s = s->next;
	}

	return s;
}

int delete_node(int k)
{
	node *s;

	s = find_node(k);

	if(s != tail)
	{
		delete_node_ptr(s);
		return 1;
	}

	return 0;
}

node *insert_node(int t, int k)
{
	node *s = NULL;
	node *i = NULL;

	s = find_node(t);

	if(s != tail)
	{
		i = insert_node_ptr(k, s);
	}

	return i;
}

node *ordered_insert(int k)
{
	node *s = NULL;
	node *i = NULL;

	s = head->next;

	while(s->key <= k && s != tail)
	{
		s = s->next;
	}

	i = insert_node_ptr(k, s);

	return i;
}

// 매개변수로 받은 노드부터 시작해서 끝까지 노드의 key 값을 출력해 줌
void print_list(node *t)
{
	while(t != tail)
	{
		printf("%-8d", t->key);
		t = t->next;
	}

	puts("\n");
}

// 모든 노드를 삭제(head, tail 제외)하고 head 노드가 가리키는 다음 노드를 tail로 초기화
node *delete_all()
{
	node *s = NULL;
	node *t = NULL;

	t = head->next;

	while(t != tail)
	{
		s = t;
		t = t->next;
		free(s);
	}

	head->next = tail;

	return head;
}

 

반응형