CS

[์ž๋ฃŒ๊ตฌ์กฐ] ๋งํฌ๋“œ๋ฆฌ์ŠคํŠธ (Linked list)

moaoh 2024. 10. 30. 18:01

๋งํฌ๋“œ๋ฆฌ์ŠคํŠธ (Linked list) ๋ž€?

  • ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ๊ฐ ๋…ธ๋“œ๊ฐ€ ๋ฐ์ดํ„ฐ์™€ ๋‹ค์Œ ๋…ธ๋“œ์˜ ์ฃผ์†Œ๋ฅผ ํฌํ•จํ•˜์—ฌ ์ˆœ์ฐจ์ ์œผ๋กœ ์—ฐ๊ฒฐ๋œ ์ž๋ฃŒ๊ตฌ์กฐ
  • ๋™์ ์œผ๋กœ ํฌ๊ธฐ๋ฅผ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Singly Linked List)
์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Doubly Linked List)

๊ธฐ์กด์ ์œผ๋กœ๋Š” ํ˜„์žฌ์˜ ๋…ธ๋“œ๊ฐ€ ๋‹ค์Œ ๋…ธ๋“œ๋งŒ์„ ์ฐธ์กฐํ•˜๋Š” ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Singly Linked List) ๋ถ€ํ„ฐ 
์ด์ „ ๋…ธ๋“œ์™€ ๋‹ค์Œ ๋…ธ๋“œ ๋ชจ๋‘๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Doubly Linked List) ๋“ฑ์œผ๋กœ ๋‹ค์–‘ํ•˜๊ฒŒ ํ™•์žฅ์ด ์ด๋ฃจ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

์žฅ๋‹จ์ 

์žฅ์ 

  • ๋™์ ์œผ๋กœ ํฌ๊ธฐ๋ฅผ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฐฐ์—ด๊ณผ ๋‹ฌ๋ฆฌ ์‚ฝ์ž… ์‚ญ์ œ์˜ ์šฉ์ดํ•˜๋‹ค.

๋‹จ์ 

  • ์ž„์˜์ ์œผ๋กœ ํŠน์ • ๋ฐ์ดํ„ฐ์˜ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ์ถ”๊ฐ€์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๋น„์šฉ์ด ๋“ ๋‹ค.

 

๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Singly Linked List)

์žฅ์ :

  • ๊ฐ ๋…ธ๋“œ๊ฐ€ ๋‹ค์Œ ๋…ธ๋“œ๋งŒ์„ ์ฐธ์กฐ๋Š” next๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ๋•Œ๋ฌธ์— ์–‘๋ฑกํ–ฅ์— ๋น„ํ•ด ๋ฉ”๋ชจ๋ฆฌ์‚ฌ์šฉ๋Ÿ‰์ด ์ค„์–ด๋“ ๋‹ค.
  • ๋…ธ๋“œ ์‚ฝ์ž…๊ณผ ์‚ญ์ œ๊ฐ€ ๋น„๊ต์  ๋‹จ์ˆœํ•˜๊ณ  ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•˜๋‹ค.

๋‹จ์ :

  • next๋งŒ ๊ฐ€์ง€๊ณ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ ๋…ธ๋“œ์—์„œ ๋‹ค์Œ ๋…ธ๋“œ๋กœ๋งŒ ์ด๋™์ด๊ฐ€๋Šฅํ•˜๊ณ  ์ด์ „๋…ธ๋“œ๋กœ๋Š” ์ด๋™์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

 

์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Doubly Linked List)

์žฅ์ :

  • prev ํฌ์ธํ„ฐ๊ฐ€ ์žˆ์–ด, ๋ฆฌ์ŠคํŠธ์˜ ์–ด๋А ์œ„์น˜์—์„œ๋“  ์•ž๋’ค๋กœ ์‰ฝ๊ฒŒ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์–‘์ชฝ ๋ฐฉํ–ฅ์œผ๋กœ ์ˆœํšŒ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ ํ•ฉํ•˜๋‹ค.

๋‹จ์ :

  • next์™€ prev ํฌ์ธํ„ฐ๋ฅผ ๋ชจ๋‘ ์œ ์ง€ํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์— ๋น„ํ•ด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•œ๋‹ค.
  • ์‚ฝ์ž…๊ณผ ์‚ญ์ œ ์‹œ next์™€ prev๋ฅผ ๋ชจ๋‘ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ์ฝ”๋“œ๊ฐ€ ๋” ๋ณต์žกํ•˜๋‹ค.

๊ตฌํ˜„

#include <list> ์‚ฌ์šฉ

#include <iostream>
#include <list>

using namespace std;

int main() {
	list<int> myList;
	myList.push_back(1);
    myList.push_back(2);
    myList.push_back(3);
    myList.push_back(4);
    myList.push_back(5);

	// push_back
	myList.push_back(6);
		
	// pop_front
	myList.pop_front();
		
	// front & back
	cout << "Front: " << myList.front() << ", Back: " << myList.back() << "\n"; // output : Front: 2, Back: 6
		
	// reverse
	myList.reverse();
		
	// ์ถœ๋ ฅ
	for (auto value : myList) {
		cout << value << " "; // output : 6 5 4 3 2
	}
		
	return 0;
}

 

Doubly Linked List ๊ตฌํ˜„

#ifndef DOUBLYLINKEDLIST_HPP_
#define DOUBLYLINKEDLIST_HPP_

#include <iostream>
#include <vector>

class Node
{
public:
	int data;
	Node *next;
	Node *prev;

	Node(int value) : data(value), next(nullptr), prev(nullptr) {}
	~Node() {}
};

class DoublyLinkedList
{
private:
	Node *head;
	Node *tail;
public:
	DoublyLinkedList() : head(nullptr), tail(nullptr) {}
	~DoublyLinkedList() {}

	void push_back(int value) {
		Node *newNode = new Node(value);
		if (tail == nullptr) {
			head = tail = newNode;
		}
		else {
			tail->next = newNode;
			newNode->prev = tail;
			tail = newNode;
		}
	}

	void push_front(int value) {
		Node *newNode = new Node(value);
		if (head == nullptr) {
			head = tail = newNode;
		}
		else {
			newNode->next = head;
			head->prev = newNode;
			head = newNode;
		}
	}

	void pop_back() {
		if (tail == nullptr) return;
		Node *temp = tail;
		tail = tail->prev;
		if (tail != nullptr) {
			tail->next = nullptr;
		} 
		else {
			head = nullptr;
		}
		delete temp;
	}

	void pop_front() {
		if (head == nullptr) return;
		Node* temp = head;
		head = head->next;
		if (head != nullptr) {
			head->prev = nullptr;
		} 
		else {
			tail = nullptr;
		}
		delete temp;
	}

	int front() {
		return head->data;
	}

	int back() {
		return tail->data;
	}

	void reverse() {
		Node* current = head;
		Node* temp = nullptr;

		tail = head;

		while (current != nullptr) {
			temp = current->prev;
			current->prev = current->next;
			current->next = temp;
			current = current->prev;
		}

		if (temp != nullptr) {
			head = temp->prev;
		}
	}
};

#endif