300 likes | 663 Vues
4 장 . 리스트 (list) 4 절 . 원형 연결 리스트 5 절 . 이중 연결 리스트. 이 완 직 ( wjlee@pnu.ac.kr ) 2010 년 1 학기. 4. 원형 연결 리스트 (Circular Linked List). 원형 연결 리스트 마지막 노드의 링크가 NULL 이 아닌 첫 번째 노드를 가리키도록 구성한 연결 리스트 컴퓨터 시스템의 입출력 버퍼 구현을 위해 사용. 원형 리스트의 첫 번째 노드로 삽입.
E N D
4장. 리스트(list) 4절. 원형 연결 리스트 5절. 이중 연결 리스트 이 완 직 (wjlee@pnu.ac.kr) 2010년 1학기
4. 원형 연결 리스트(Circular Linked List) • 원형 연결 리스트 • 마지막 노드의 링크가 NULL이 아닌 첫 번째 노드를 가리키도록 구성한 연결 리스트 • 컴퓨터 시스템의 입출력 버퍼 구현을 위해 사용
원형 리스트의 첫 번째 노드로 삽입 void addFrontNode(linkedList_h* L, element x) { ListNode* newNode; ListNode* p; newNode = getNode(); //우측 아래 코드 참조 newNode->data = x; //데이터 필드에 데이터 설정 if(L->head == NULL){ // ❶ 공백인 경우 L->head = newNode; // ❶-가 newNode->link = newNode; // ❶-나 } else{ // ❷ p = L->head; // ❷-가 while(p->link != L->head) // ❷-나 p=p->link; newNode->link = p->link; // ❷-다 p->link = newNode; // ❷-라 L->head = newNode; // ❷-마 } }
4. 원형 연결 리스트(Circular Linked List) ❶ 원형 리스트가 공백 리스트인 경우에 삽입하는 노드 newNode는 리스트의 첫 번째 노드이자 마지막 노드가 되어야 한다. ❶-가) 삽입할 새 노드의 주소를 포인터 head에 저장하여 포인터 head가 새로운 노드를 가리키게 한다. ❶-나) 새 노드의 주소를 링크 필드에 저장하여 새 노드가 자기 자신을 가리키게 함으로써 첫번째 삽입한 노드가 마지막 노드가 되도록 지정한다.
4. 원형 연결 리스트(Circular Linked List) ❷ 원형 리스트가 공백 리스트가 아닌 경우에는 단순 연결 리스트처럼 마지막 노드에 새로운 노드를 삽입한다. ❷-가) 리스트가 공백 리스트가 아닌 경우에는 첫 번째 노드의 주소를 임시 순회 포인터 p에 저장하여 노드 순회의 시작점을 지정한다.
4. 원형 연결 리스트(Circular Linked List) ❷-나)while 반복문을 수행하면서 순회 포인터 p가 링크를 따라 마지막 노드까지 이동한다
4. 원형 연결 리스트(Circular Linked List) ❷-다) 리스트의 마지막 노드의 링크값을 노드 newNode 링크에 저장하여 노드 newNode가 노드 p의 다음 노드를 가리키게 한다. 리스트 head는 원형 연결 리스트이므로 마지막 노드의 다음 노드는 리스트의 첫 번째 노드가 된다.
4. 원형 연결 리스트(Circular Linked List) ❷-라 포인터 newNode의 값을 포인터 p가 가리키고 있는 마지막 노드의 링크에 저장하여 리스트의 마지막 노드가 노드 newNode를 가리키게 한다.
❷-마 노드 newNode의 주소를 리스트 포인터 head에 저장하여 노드 newNode가 리스트의 첫 번째 노드가 되도록 지정한다. 원형 연결 리스트의 첫 번째 노드에 삽입을 완성하고 난 후의 상태
원형 리스트의 중간 노드로 삽입 • void insertMiddleNode(linkedList_h* L, ListNode *pre, element x) • { • ListNode* newNode; • ListNode* p; • newNode = getNode(); //새로 추가할 노드를 저장할 메모리 할당 • newNode->data = x; //데이터 필드에 데이터 설정 • if(L->head == NULL){ // ❶ 공백 원형 연결 리스트인 경우 • L->head = newNode; • newNode->link = newNode; • } • else{ // ❷ • newNode->link = pre->link; // ❷-가 • pre->link = newNode; // ❷-나 • } • }
4. 원형 연결 리스트(Circular Linked List) ❶ 원형 리스트가 공백 리스트인 경우에 중간 노드로 삽입하는 알고리즘은 첫 번째 노드에 삽입하는 알고리즘과 동일하다. ❷-가) 노드 pre의 다음 노드로 newNode를 삽입하기 위해서 먼저 노드 pre의 다음 노드(pre->link)를 newNode의 다음 노드(newNode->link)로 연결한다.
4. 원형 연결 리스트(Circular Linked List) ❷-나) 노드 newNode의 주소를 노드 pre의 링크에 저장하여 노드 pre가 노드 newNode를 가리키게 한다.
5. 이중 연결 리스트(Double Linked List) • 단순 연결 리스트의 단점 • 리스트를 반대 방향으로 순회할 수 없다. • 노드 삭제 시, 삭제하고자 하는 노드의 포인터로만 해당 노드를 삭제 할 수 없음 • 이중 연결 리스트 • 연결 리스트의 양쪽 방향 탐색이 가능하도록 구성 • 양방향 링크를 사용 • llink: 왼쪽 방향(선행 노드)를 가르키는 포인터 • rlink: 오른쪽 방향(후행 노드)를 가르키는 포인터
5. 이중 연결 리스트(Double Linked List) • 구조체 정의
5. 이중 연결 리스트(Double Linked List) • 이중 원형 연결 리스트(doubly circular linked list) • 첫번째 노드의 llink는 마지막 노드를 포인팅 • 마지막 노드의 rlink는 첫번째 노드를 포인팅 • head 노드는 첫번째 노드를 포인팅 • 이중 원형 연결 리스트는 NULL 포인터를 사용하지 않는다.
이중 원형 연결 리스트 초기화 함수 • linkedList_h* createLinkedList_h(void) • { • linkedList_h* L; • //헤더의 공간을 확보 • L = (linkedList_h*)malloc(sizeof(linkedList_h)); • ListNode *newNode = getNode(); • L->head = newNode; • L->head->llink = L->head; • L->head->rlink = L->head; • return L; • }
5. 이중 연결 리스트(Double Linked List) • 중간 노드 삽입 함수 • // x 값을 가지는 노드를 생성하여, pre가 가르키는 노드 다음에 삽입 • void dinsert(linkedList_h* L, ListNode *pre, element x) • { • //새로 추가할 노드를 저장할 메모리 할당 • ListNode* newNode = getNode(); • newNode->data = x; //데이터 필드에 데이터 설정 • newNode->llink = pre; // ❶ • newNode->rlink = pre->rlink; // ❷ • pre->rlink->llink = newNode; // ❸ • pre->rlink = newNode; // ❹ • }
5. 이중 연결 리스트(Double Linked List) ❶ 포인터 pre의 값을 삽입할 노드인 newNode의 llink에 저장하여 노드 pre를 노드 newNode의 왼쪽 노드로 연결한다. ❷ 노드 pre의 rlink를 노드 newNode의 rlink에 저장하여 노드 pre의 오른쪽 노드를 삽입할 노드 newNode의 오른쪽 노드로 연결한다.
5. 이중 연결 리스트(Double Linked List) ❸ 포인터 newNode의 값을 노드 newNode의 오른쪽 노드(newNode->rlink)의 llink에 저장하여 노드 newNode의 오른쪽 노드의 왼쪽 노드로 노드 newNode를 연결한다.
5. 이중 연결 리스트(Double Linked List) ❹ 새 노드인 newNode의 주소를 노드 pre의 rlink에 저장하여 노드 newNode를 노드 pre의 오른쪽 노드로 연결한다. 다음은 이중 원형 연결 리스트에 노드를 삽입한 후의 상태이다.
이중 원형 연결 리스트의 노드 삭제 함수 • void ddelete(linkedList_h* L, ListNode* deleted) • { • deleted->llink->rlink = deleted->rlink; // ❶ • deleted->rlink->llink = deleted->llink; // ❷ • free(deleted); // ❸ • }
❶ 삭제할 노드의 오른쪽 노드의 주소(deleted->rlink)를 삭제할 노드의 왼쪽 노드(deleted->llink)의 오른쪽 링크(rlink)에 저장한다.
❷ 삭제할 노드의 왼쪽 노드 주소(deleted->llink)를 삭제할 노드의 오른쪽 노드(deleted->rlink)의 왼쪽 링크(llink)에 저장한다.
5. 이중 연결 리스트(Double Linked List) ❸ 삭제한 노드를 자유 공간 리스트에 반환한다.