NAVER

질문 C언어 이진트리 삭제좀 도와주세요
비공개 조회수 428 작성일2019.08.19
이진트리 알고리즘인데 삭제가 왜안되는지 모르겠어요 제발 도와주시요 ㅠㅜ 삭제는 delete함수부분입니다

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

typedef struct Node
{
int data;
struct Node* Llink;
struct Node* Rlink;
}Node;

void Input(Node* root);
void Output(Node* root);
void Delete(Node** root);

int main(void)
{
Node* root = NULL;
int n;

do
{

printf("* 1.입력 2.출력 3.검색 4.삭제 5.종료 *\n");

printf("실행할 프로그램 번호를 입력하세요.:");
scanf("%d", &n);

switch (n)
{
case 1:
if (root == NULL)
{
root = (Node*)malloc(sizeof(Node));
root->data = NULL;
root->Llink = NULL;
root->Rlink = NULL;
}
Input(root);
printf("\n");
break;
case 2:
if (root == NULL)
{
printf("데이터가 존재하지 않습니다.\n");
}
else if (root != NULL)
{
printf("전위 출력:");
}
Output(root);
printf("\n");
break;
case 3:

Search(root);
printf("\n");
break;
case 4:

Delete(&root);
printf("\n");
break;
case 5:

printf("프로그램이 종료됩니다.\n");
break;

default:

printf("잘못 입력하셨습니다.\n");
break;

}
} while (n != 5);
}

void Input(Node* root)
{
Node* r = root;
int data;

printf(" 데이터값을 입력하세요. : ");
scanf("%d", &data);

if (r->data == NULL)
{
r->Llink = r->Rlink = NULL;
r->data = data;
return;
}
else
{
Node* newnode = (Node*)malloc(sizeof(Node));
newnode->Llink = NULL;
newnode->Rlink = NULL;
newnode->data = NULL;
newnode->data = data;

while (r != NULL)
{
if (r->data > data)
{
if (r->Llink == NULL)
{
r->Llink = newnode;
return;
}
if (r->Llink->data == data)
{
printf("중복된 데이터 값 입니다.\n");
return;
}
r = r->Llink;
}
else if (r->data < data)
{
if (r->Rlink == NULL)
{
r->Rlink = newnode;
return;
}
if (r->Rlink->data == data)
{
printf("중복된 데이터 값 입니다.\n");
return;
}

r = r->Rlink;
}
else if (data == r->data)
{
printf("이미 존재하는 데이터 값 입니다.\n");
return;
}
}

}
return;
}

void Output(Node* root)
{
Node* r = root;

if (r == NULL)
{
return;
}
printf("% d ", r->data);
Output(r->Llink);
Output(r->Rlink);
}

void Delete(Node** root)
{
int del;
Node* k;
Node* r = *root;

printf("삭제할 데이터 값을 입력하세요.:");
scanf("%d", &del);

if (r == NULL)
{
printf("데이터 값이 존재하지 않습니다.\n");
return;
}

while (r != NULL)
{
if (del == r->data)
{

printf("삭제 완료.\n");
return;
}
else if (r->data > del)
{
if (r->Llink == NULL)
{
printf("데이터 값이 존재하지 않습니다.\n");
return;
}
else if (r->data == del)
{
k = r;
r = r->Llink;
k->Llink = r->Llink;
free(r);
printf("삭제 완료.\n");
return;
}
r = r->Llink;
}
else if (r->data < del)
{
if (r->Rlink == NULL)
{
printf("데이터 값이 존재하지 않습니다.\n");
return;
}
else if(r->data == del)
{
k = r;
r = r->Llink;
k->Llink = r->Llink;
free(r);
printf("삭제 완료.\n");
return;
}
r = r->Rlink;
}
}
return;
}
프로필 사진

답변자님,

정보를 공유해 주세요.

2 개 답변
2번째 답변
프로필 사진
meta****
태양신
본인 입력 포함 정보

Delete 함수에서 아래 부분인데 지울 값을 노드에서 찾은 경우에 지우지 않고 삭제 완료라고 출력하고 반환하네요.

삭제 완료라고 출력한다고 실제 삭제가 된다고 생각하시는건 아니시죠? ^^;

while (r != NULL)

{

if (del == r->data)

{

printf("삭제 완료.\n");

return;

}

...

}

2019.08.19.

  • 채택

    질문자가 채택한 답변입니다.

이 답변의 추가 Q&A
질문자와 답변자가 추가로 묻고 답하며 지식을 공유할 수 있습니다.
도움이 되었다면 UP 눌러주세요!
UP이 많은 답변일수록 사용자들에게 더 많이 노출됩니다.
1번째 답변
프로필 사진
포로리
달신 eXpert
IT/인터넷업 #프로그래머 게임프로그래밍 11위, C, C++, 자바, JSP 52위 분야에서 활동
본인 입력 포함 정보

문제 푸시는 알고리즘의 시작부터 잘못되었습니다.

이진 트리에서 delete를 해서 해당 노드를 지웠을 때 그 자리를 대체할 node는 일반적으로 조금 다른 해법을 쓸텐데요?

예제를 보여드리겠습니다.

위와 같은 트리가 있는데 오렌지 색이 지워질 노드라고 가정할께요.

만약 오렌지 노드를 제거하고 왼쪽의 초록색 child가 자리를 차지하면 다음과 같겠지요?

녹색의 R-link가 선이 두개가 됩니다. 곧 하나의 링크는 dead link가 되버리겠지요.

반대로 오른쪽의 파랑 노드를 오렌지 노드에 대체하면 아래와 같겠지요?

역시 L-link가 겹치면서 이진트리가 망가집니다.

아마 이론으로 배우셨을텐데요. 이진트리를 유지하면서 노드를 지우는 가장 쉬운 방법은

좌측 우선인 경우는 좌측 노드 중 가장 큰 child를 올리고

우측 우선인 경우 우측 노드 중 가장 작은 child를 올리면서 이진트리를 유지하는 겁니다.

저는 좌측우선에서 가장 큰 값을 가진 보라색 노드를 선택했습니다.

보라색 노드를 위로 올려보죠.

보라색 노드가 자리를 잡으면 녹색은 당연히 보라색보다 작고, 파랑색은 당연히 보라색 보다 큽니다.

이진 트리를 유지하면서 변환에 성공한 상황입니다.

물론 delete에 다른 예외 케이스들이 있어서 이렇게 간단히 짜이지는 않습니다만

문제의 출발이 잘못되었다는 점을 설명드린 겁니다.

그리고, 프로그래밍 하실때 root 노드가 예외처럼 잡혀있는데

만약 del이 root노드라면 어떻게 하실 건가요?

root의 L-link, R-link를 찾으실게 아니라 root 노드 자체부터 제거가능하도록 고민하셔야 할 것 같습니다.

2019.08.19.

포로리님의 엑스퍼트 상품
답변자에게 더 자세한 맞춤 상담하고 싶다면 엑스퍼트를 이용해보세요!
바로가기
도움이 되었다면 UP 눌러주세요!
UP이 많은 답변일수록 사용자들에게 더 많이 노출됩니다.