코딩 이야기

[C언어] 단순 연결 리스트에서 노드 삭제, 탐색 함수 구현

고주망고 2021. 10. 20. 07:42

단순 연결 리스트에서 노드 삭제탐색하는 함수를 구현해보겠습니다.

 

 

삭제 함수 이름 deleteNode

탐색 함수 이름 searchNode

각 함수를 한번 호출할때마다 printList(L)로 리스트 전체를 출력해주면서 진행해보겠습니다.

 

이번 포스팅에서 중점은 바로 삭제를 하기 위한 값 탐색!! 부분입니다.

저 같은 경우는 !strcmp(var1,var2)를 이용하여 값을 찾은것을 아래 코드에서 확인해보시기 바랍니다.


실행 예시

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct ListNode {
	char data[4];
	struct ListNode* link;
}listNode;

typedef struct {
	listNode* head;
}linkedList_h;


linkedList_h* createdLinkedList_h(void) {
	linkedList_h* L;
	L = (linkedList_h*)malloc(sizeof(linkedList_h));
	L->head = NULL;
	return L;
}

void freelinkedList_h(linkedList_h* L) {
	listNode* p;
	while (L->head != NULL) {
		p = L->head;
		L->head = L->head->link;
		free(p);
		p = NULL;
	}
}

void printList(linkedList_h* L) {
	listNode* temp;
	temp = L->head;

	printf(" L -> ");
	while (temp != NULL) {
		printf(" %s", temp->data);
		temp = temp->link;
	}
	printf("\n\n");
}

//첫번쨰 노드로 넣는 경우, 매개변수: (리스트,넣을 값)
void insertFirstNode(linkedList_h* L,char* x) {
	listNode* newNode;
	newNode = (listNode*)malloc(sizeof(listNode));
	strcpy(newNode->data, x);
	newNode->link = L->head;
	L->head = newNode;
}

//중간 노드로 넣는 경우, 매개변수:(리스트,이전 노드,넣을 값)
void insertMiddleNode(linkedList_h* L, char* pre, char* x) {
	listNode* newNode;
	listNode* findpre;
	newNode = (listNode*)malloc(sizeof(listNode));
	strcpy(newNode->data, x);

	/*이전 노드를 찾는것이 중요함*/
	findpre = L->head;
	while (strcmp(findpre->data,pre)) {
		findpre = findpre->link;
	}

	if (L->head == NULL) {
		newNode->link = NULL;
		L->head = newNode;
	}
	else if (pre == NULL) { //이전 노드 오지않은 경우
		newNode->link = NULL;
		L->head = newNode;
	}
	else  { // 연결 리스트가 공백 리스트가 아니고 pre가 NULL이 아닌 경우
		newNode->link = findpre->link;
		findpre->link = newNode;
	}
}

//마지막 노드로 넣는 경우, 매개변수:(리스트,넣을 값)
void insertLastNode(linkedList_h* L, char* x) {
	listNode* newNode;
	listNode* temp;
	newNode = (listNode*)malloc(sizeof(listNode));
	strcpy(newNode->data, x); //newNode의 data값 설정
	newNode->link = NULL; //마지막 노드이기때문에 NULL값이 들어가야한다.
	if (L->head == NULL) {
		L->head = newNode;
		return;
	}
	else {
		temp = L->head;
		while (temp->link!=NULL) { //마지막 노드 찾기
			temp = temp->link;
		}
		temp->link = newNode;
	}
}

void deleteNode(linkedList_h* L, char* x) {
	listNode* pre;
	listNode* item;

	pre=L->head;
	//삭제할값의 이전값 탐색
	while (pre!=NULL) {
		if (!strcmp(pre->link->data,x)) {//값을 찾은 경우
			break;
		}
		pre = pre->link;
	}	
	item = pre->link;

	//삭제할 값이 첫 노드에 있는 경우
	if (pre == L->head) {
		L->head = item->link;
	}
	else if (item->link == NULL) {//삭제할값이 가장 마지막 노드인 경우
		pre->link = NULL;
		free(item);
	}
	else {
		pre->link = item->link;
		free(item);
	}
}


void findNode(linkedList_h* L, char* x) {
	listNode* temp;
	temp = L->head;
	while (temp!=NULL) {
		if (!strcmp(temp->data, x)) { // 같은경우
			printf("\n[%s]를 찾았습니다!! \n", x);
			return;
		}
		else {
			temp = temp->link;
		}
	}
	printf("\n[%s]를 찾지못했습니다!! \n",x);
}



void main() {
	linkedList_h* L;
	L = createdLinkedList_h();
	printf("공백 리스트 생성\n");
	printList(L);

	printf("리스트에 [수]노드 삽입하기\n");
	insertFirstNode(L, "수");
	printList(L);

	printf("리스트 마지막에 [금]노드 삽입하기\n");
	insertLastNode(L, "금");
	printList(L);

	printf("리스트 마지막에 [일]노드 삽입하기\n");
	insertLastNode(L, "일");
	printList(L);

	printf("리스트 [수] 뒤에 [목]노드 삽입하기\n");
	insertMiddleNode(L, "수", "목");
	printList(L);

	printf("리스트 [금] 뒤에 [토]노드 삽입하기\n");
	insertMiddleNode(L, "금", "토");
	printList(L);

	printf("리스트 처음에 [월]노드 삽입하기\n");
	insertFirstNode(L, "월");
	printList(L);

	printf("리스트 [월] 뒤에 [화]노드 삽입하기\n");
	insertMiddleNode(L, "월", "화");
	printList(L);

	printf("월 화 수 목 금 토 일 완성!!\n\n\n");

	printf("<탐색 연산, 삭제 연산 구현해보기>\n");
	printf("리스트에서 [수]노드 탐색하기");
	findNode(L, "수");
	printList(L);

	printf("리스트에 있는 [수]노드 삭제하기\n");
	deleteNode(L, "수");
	printList(L);

	printf("리스트에서 [수]노드 탐색하기");
	findNode(L, "수");
	printList(L);

	printf("리스트 공간 해제\n");
	freelinkedList_h(L);
	printList(L);
}