작성
·
388
0
섹션1 - '연결 리스트 구현 연습' 강의에 대한 질문입니다.
위와 같이 Remove를 구현했습니다. (강의에서 head, tail에 해당하는 변수명은 first, last로 선언했습니다)
1) 삭제하려는 방이 첫 번째 요소인지와 이전 방이 null인지를 두 번 체크하는데, 그렇게 하지 않으면 예외가 발생하지 않는지 궁금합니다. (즉 위와 같이 if문을 작성하면 에러가 날 수 있나요?)
2) 삭제하려는 방을 따로 null처리할 필요는 없나요? room = null을 적어보니 사용되지 않는 코드처럼 회색으로 떠서요.
답변 4
1
그 부분은 무조건 처리를 해줘야 합니다.
이미 삭제된 방을 가리키고 있는 것도 자료구조 차원에서의 큰 문제이고,
추가로 메모리 측면에서도 문제가 됩니다.
C++과 다르게 C#는 메모리 해제를 직접하지 않고
아무도 해당 객쳋를 참조하지 않을 때 Garbage Collector라는 애가 알아서 메모리를 수거해갑니다.
그런데 누군가가 해당 객체를 참조하고 있으면, 해당 객체가 메모리에서 해제되지 않게 됩니다.
참고로 제가 작성한 코드를 유심히 보시면
room.Next.Prev = room.Prev 부분에서 말씀하신 부분의 처리를 간접적으로 해주고 있습니다.
왜냐하면 만약에 삭제할 대상이 첫번째 방이었다면, room.Prev가 null인 상태일테니,
결과적으로 room.Next.Prev = null로 밀어주기 때문이죠.
1
안녕하세요,
구현 방법이야 다양하니 동작만 하면 일단 장땡입니다.
그와는 별개로 보통 실수를 줄이려면 본인만의 스타일과 공식을 암암리에 만들면 좋은데,
기저사항 (매우 예외적인 케이스)을 가장 먼저 처리하는게 좋기 때문에 Head/Tail 비교가 두번 들어갔습니다.
아무튼 작성해주신 코드에서 수상한 부분이 몇몇 보이네요.
1) 일단 last, first는 갱신이 되지 않고 있는 것 같네요.
room은 어차피 삭제될 예정인데 굳이 room.prev = last를 해줄 필요가 없어 보입니다.
(last = room.prev를 의미하신건가요?)
2) 마지막 방이 아니라면 room.prev.next = room.next를 실행하는데,
하필 첫 방을 삭제했다면 room.prev.next에서 크래시가 나지 않을까요?
아니면 last, first 의미를 반대로 사용하고 계셨을 수도 있겠네요.
사실 눈으로 확인하는 것보다 가장 확실한 방법은 [처음] [마지막] [중간] 데이터를 한번씩 삭제해보는 것입니다.
정상적으로 다 되는지 테스트를 해보시면 보다 빠르게 버그 유무를 찾을 수 있을거에요.
그리고 두번째 질문으로 주신 [삭제하려는 방을 null 처리]하는 것은 아무 의미가 없습니다.
여기서 null 처리한다고 실제로 함수 호출한 밖에서도 null 처리가 되지 않기 때문이죠.
마치 임시 변수 Room<T> temp = room; 을 한 다음 temp = null 처리하고 room이 null 되길 기대한 셈이 됩니다.
0
아 맨 앞의 요소가 삭제될 때 두번째 방의 prev에 사실상 null을 대입하게 되는거군요. 그것도 모르고 null도 대입해보고 동적 배열에서 한거처럼 default도 해보고 뻘짓을... ㅋㅋㅋ
상세한 답변 정말 감사합니다!
0
감사합니다. 말씀하신 대로 first = room.next; 이 맞고, if문 내의 first와 last도 반대로 썼네요.
if (room != first) room.prev.next = room.next;
else first = room.next;
if (room != last) room.next.prev = room.prev;
else last = room.prev;
이렇게 수정하니 처음 가운데 끝 삭제 모두 에러 없이 동작하는 듯합니다.
한 가지 궁금한게 더 생겼는데요, 지우려는 방이 첫 번째 방이면 두 번째 방을 first로 지정하잖아요? 그런데 first에 해당하는 방이 여전히 prev값을 가지고 있는데, 이 부분은 그대로 두어도 되나요? 강의에서 구현하지는 않았지만 node.Previous 같은걸로 첫번째 방의 이전 값을 불러올 때 연결 리스트에서 제거된 값이 여전히 호출될 것 같아서요.