연결리스트의 3가지 기본 유형.
- 단일 연결
- 이중 연결
- 원형 연결
일반적인 단일 연결리스트의 구조는 아래와 같다.
typedef struct IntElement{
struct IntElement * next;
int data ;
}IntElement;
next 포인터를 구조체나 클래스의 맨 앞 쪽에 넣어두면 그 원소에 어떤 데이터가 들어가든 제대로 동작하는 포괄적인 리스트 처리 루틴을 더 쉽게 만들수 있다는 장점이 있다.
다른 언어에서는 임의의 객체에 대한 레퍼런스를 각 원소에 저장하는 식으로 연결 리스트 루틴을 만드는 것이 일반적.
public class ListElement{
ListElement next;
Object data;
public ListElement( Object data ){
this.data = data;
}
}
단일 연결리스트에서 전체 원소를 종주하려면 반드시 첫번째 원소의 위치를 알아야한다.
이중 연결리스트에서는 어디에서든 시작하면 된다.
원형 연결리스트( 테일 -> 헤드 ) 이런 구조.
기초적인 연결리스트(단일 연결리스트) 연산
헤드 원소 추적.
단일 연결리스트에서 헤드에 대한 정보를 상실할 경우 접근 자체가 어려워지기 때문에 새로운 원소를 첫번째 원소 앞에 추가한다거나 리스트의 첫 번째 원소를 제거할 때 리스트의 헤드 포인터 또는 레퍼런스를 갱신해야 한다.
C/C++에서 종종 포인터를 잘못 사용하여 실수하는 일이 발생.
bool insertInFront(IntElement * head , int data)
{
IntElement * newElem = new IntElement;
newElem->data = data ;
head = newElem;
// 이렇게 할 경우 연결(리스트)가 생성되지 않음.
return true;
}
헤드 포인터에 대한 지역 변수 사본만을 갱신하기 때문에 이 코드는 제대로
동작하지 않는다.
bool insertInForm(IntElement **head, int data)
{
IntElement* newElem = new IntElement ;
newElem->data = data;
*head = newElem;
return true;
}
리스트의 종주시 반드시 체크해야 할 것.
리스트를 종주할 때는 반드시 연결 리스트가 끝났는지를 확인해야 한다.
원소의 삽입 및 삭제.
삭제 및 삽입을 하려면 삽입 또는 삭제할 위치의 바로 앞에 있는 원소에 대한 포인터 또는 레퍼런스가 필요하다.
bool deleteEle( IntElement ** head, IntElement * deleteMe)
{
IntElement * elem = *head;
if(deleteMe == *head )
{
// 헤드 일경우
// 따로 취급하는 이유. 헤드는 가장 상단에 위치 하므로 앞에 있는 원소와 뒤에있는 원소를 연결할 필요가 없다.
*head = elem->next;
delete deleteMe;
return true;
}
while(elem)
{
if(elem->next == deleteMe)
{
// elem->next임에 주의하자.
elem->next = deleteMe->next;
delete deleteMe;
return true;
}
elem = elem->next;
}
return false;
}
리스트 전체를 지워야 할 경우
void deleteList(IntElement ** head)
{
IntElement * deleteMe = *head;
while(deleteMe)
{
IntElement * next = deleteMe->next ;
delete deleteMe;
deleteMe = next;
}
*head = NULL;
}
이런식으로 2개의 포인터를 지정해 주어야 한다.
'단일 연결리스트'에 해당되는 글 1건
- 2007/12/16 프로그래밍 면접 이렇게 준비한다 #4 연결리스트.
TAG 단일 연결리스트

