Post

๐Ÿข 2. Data Structures

๐Ÿ’ก ์ž๋ฃŒ๊ตฌ์กฐ

  • ๋ฐฐ์—ด

  • ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ

  • ์Šคํƒ

  • ํ

  • ํ•ด์‹œ ํ…Œ์ด๋ธ”


๐Ÿซง ๋ฐฐ์—ด๊ณผ ๋ฌธ์ž์—ด

โค๏ธ ํ•ด์‹œํ…Œ์ด๋ธ” (hash table)

ํšจ์œจ์ ์ธ ํƒ์ƒ‰์„ ์œ„ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๋กœ์„œ, key๋ฅผ value ์— ๋Œ€์‘์‹œํ‚ด

์ตœ์•…์˜ ๊ฒฝ์šฐ O(n) // n์€ ํ‚ค์˜ ๊ฐœ์ˆ˜

์ตœ์„ ์˜ ๊ฒฝ์šฐ O(1)

1) ํ‚ค์˜ ํ•ด์‹œ ์ฝ”๋“œ ๊ณ„์‚ฐ

  • ํ‚ค์˜ ์ž๋ฃŒํ˜•์€ ๋ณดํ†ต int or long
  • ํ‚ค์˜ ๊ฐœ์ˆ˜ ๋ฌดํ•œ (int ๋Š” ์œ ํ•œ)

2) hash(key) % array_length ๋ฐฉ์‹์œผ๋กœ ํ•ด์‹œ ์ฝ”๋“œ ์ด์šฉํ•ด ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค ๊ตฌํ•จ

  • ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ ํ•ด์‹œ ์ฝ”๋“œ๊ฐ€ ๊ฐ™์€ ์ธ๋ฑ์Šค ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ์Œ

3) ๋ฐฐ์—ด์˜ ๊ฐ ์ธ๋ฑ์Šค์—๋Š” ํ‚ค์™€ ๊ฐ’์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ์กด์žฌ

  • ํ‚ค์™€ ๊ฐ’์„ ํ•ด๋‹น ์ธ๋ฑ์Šค์— ์ €์žฅ (๋ฐ˜๋“œ์‹œ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ์ด์šฉ!)
  • ๐Ÿ’ฅ ์ถฉ๋Œ : ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ ํ‚ค๊ฐ€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฑฐ๋‚˜, ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ ํ•ด์‹œ ์ฝ”๋“œ๊ฐ€ ๊ฐ™์€ ์ธ๋ฑ์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒฝ์šฐ

โ‡’ ํ‚ค์— ์ƒ์‘ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์œ„๋ฅผ ๋ฐ˜๋ณต!

โ‡’ ์ฃผ์–ด์ง„ ํ‚ค๋กœ๋ถ€ํ„ฐ ํ•ด์‹œ ์ฝ”๋“œ๋ฅผ ๊ณ„์‚ฐ, ํ•ด์‹œ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ด ์ธ๋ฑ์Šค ๊ณ„์‚ฐ, ํ•ด๋‹น ํ‚ค์— ์ƒ์‘ํ•˜๋Š” ๊ฐ’์„ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ ํƒ์ƒ‰

1
2
3
4
โž• ๊ท ํ˜• ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ (balanced binary search tree) 
: ํƒ์ƒ‰ ์‹œ๊ฐ„์€ O(logN)
: ํฌ๊ธฐ๊ฐ€ ํฐ ๋ฐฐ์—ด์„ ๋ฏธ๋ฆฌ ํ• ๋‹นํ•ด ๋†“์ง€ ์•Š์•„๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ ์€ ๊ณต๊ฐ„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
: ํ‚ค์˜ ์ง‘ํ•ฉ์„ ํŠน์ • ์ˆœ์„œ๋Œ€๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅ

โค๏ธ ArrayList ์™€ ๊ฐ€๋ณ€ ํฌ๊ธฐ ๋ฐฐ์—ด

  • ArrayList
    • ๋™์  ๊ฐ€๋ณ€ ํฌ๊ธฐ ๊ธฐ๋Šฅ ๋‚ด์žฌ์˜ ๋ฐฐ์—ด์ผ ๋•Œ ์‚ฌ์šฉ
    • ํ•„์š”์— ๋”ฐ๋ผ ํฌ๊ธฐ๋ฅผ ๋ณ€ํ™” ๊ฐ€๋Šฅ
    • O(1)์˜ ์ ‘๊ทผ ์‹œ๊ฐ„์„ ์œ ์ง€
    • ๋ฐฐ์—ด์ด ๊ฐ€๋“ ์ฐจ๋ฉด, ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋ฅผ ๋‘ ๋ฐฐ๋กœ ๋Š˜๋ฆผ
      • O(n)์œผ๋กœ ๋Š˜๋ ค์ง€์ง€๋งŒ, ์ƒํ™˜ ์ž…๋ ฅ ์‹œ๊ฐ„์œผ๋กœ ์ธํ•ด O(1)
      • n๊ฐœ์˜ ์›์†Œ๋ฅผ ์‚ฝ์ž…ํ•  ๋•Œ ์†Œ์š” ์ž‘์—…์€ O(n)
      • ํ‰๊ท ์ ์œผ๋กœ ๊ฐ ์‚ฝ์ž…์€ O(1)
โค๏ธ StringBuilder

๊ฐ€๋ณ€ ํฌ๊ธฐ ๋ฐฐ์—ด์„ ์ด์šฉํ•ด์„œ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ๋ฌธ์ž์—ด ๋ณต์‚ฌ

1
2
3
4
5
6
7
String joinWords(String[] words) {
  StringBuilder sentence = new StringBuilder();
  for (String w : words) {
      sentence.append(w);
  }
  return sentence.toString();
}

๐Ÿซง ๋ฒกํ„ฐ ๊ตฌํ˜„ํ•˜๊ธฐ

โžก๏ธ size() - ํ•ญ๋ชฉ์˜ ๊ฐœ์ˆ˜

1
2
3
4
public static void main(String[] args){
    ArrayList<Object> sizeTest = new ArrayList<Object>();
    System.out.println( sizeTest.size() );  // 0
}

โžก๏ธ capacity() - ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š” ํ•ญ๋ชฉ์˜ ์ตœ๋Œ€ ๊ฐœ์ˆ˜

1
2
3
4
5
public static void main(String[] args) {
    StringBuffer buff = new StringBuffer(20);
    buff.append("GwangJik");
    System.out.println("Capacity : " + buff.capacity());    // 20
}

โžก๏ธ is_empty()

1
2
3
4
String test = null;
if(test != null && test.isEmpty()) {
    System.out.println(test);
}

โžก๏ธ at(index) - ์ธ๋ฑ์Šค์— ์žˆ๋Š” ํ•ญ๋ชฉ์„ ๋Œ๋ ค์ฃผ๊ณ , ์ธ๋ฑ์Šค๊ฐ€ ๋ฒ”์œ„ ๋ฐ–์ด๋ฉด ์—๋Ÿฌ๋ฅผ ๋ƒ„

1
2
3
4
int digitStr = "456";

// 0๋ฒˆ์งธ์— ์žˆ๋Š” char ๊ฐ’์„ ๋ฆฌํ„ด
digitStr.charAt(0) // 4

โžก๏ธ push(item)

1
2
var fruit = ["์‚ฌ๊ณผ", "๋ฐฐ", "ํฌ๋„"];
fruit.push("๋”ธ๊ธฐ");      // ๋ฐฐ์—ด ๋’ค์ชฝ์— ๋ฐ์ดํ„ฐ ์‚ฝ์ž… ["์‚ฌ๊ณผ", "๋ฐฐ", "ํฌ๋„", "๋”ธ๊ธฐ"]

โžก๏ธ insert(index, item) - index์— item์„ ์‚ฝ์ž…ํ•˜๊ณ  ๊ธฐ์กด ์ธ๋ฑ์Šค์˜ ๊ฐ’๋ถ€ํ„ฐ ์ญ‰ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์‰ฌํ”„ํŠธ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ArrayListDemo {
    public static void main(String[] args)
    {
        // create an empty list with an initial
        // capacity
        List<String> list = new ArrayList<String>(5);
 
        // use add() method to initially
        // add elements in the list
        list.add("Geeks");
        list.add("For");
        list.add("Geeks");
       
        // Add a new element at index 0
        list.add(0, "Hello");
       
        // prints all the elements available in list
        for (String str : list) {
            System.out.print(str + " ");
        }
    }
}
// Hello Geeks For Geeks

โžก๏ธ prepend(item) - ๋งจ ์•ž์— ์›์†Œ๋ฅผ ์‚ฝ์ž…

1
2
3
int[] arr = { 10, 20, 30 };

arr = ArrayUtils.add(arr, 40);

โžก๏ธ pop() - ๋งˆ์ง€๋ง‰ ์›์†Œ๋ฅผ ์‚ญ์ œํ•˜๊ณ  ๊ฐ’์„ ๋Œ๋ ค์ค€๋‹ค

1
2
var fruit = ["์‚ฌ๊ณผ", "๋ฐฐ", "ํฌ๋„"];
fruit.pop();             // ๋ฐฐ์—ด ๋’ค์ชฝ์˜ ๋ฐ์ดํ„ฐ ์ œ๊ฑฐ ["์‚ฌ๊ณผ", "๋ฐฐ"]

โžก๏ธ delete(index) - delete item at index, shifting all trailing elements left

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.io.File;  // Import the File class

public class DeleteFile {
  public static void main(String[] args) { 
    File myObj = new File("filename.txt"); 
    if (myObj.delete()) { 
      System.out.println("Deleted the file: " + myObj.getName());
    } else {
      System.out.println("Failed to delete the file.");
    } 
  } 
}

// Deleted the file: filename.txt

โžก๏ธ remove(item) - looks for value and removes index holding it (even if in multiple places)

1
2
3
4
5
6
7
8
9
10
11
String[] fruitsArray = {"apple", "banana", "kiwi", "mango"};
ArrayList<String>  fruits = new ArrayList<>(Arrays.asList(fruitsArray));
System.out.println("all: " + fruits.toString());

String returned = fruits.remove(2);
System.out.println("remove(2): " + fruits.toString());
System.out.println("returned: " + returned);

// all: [apple, banana, kiwi, mango]
// remove(2): [apple, banana, mango]
// returned: kiwi

โžก๏ธ find(item) - looks for value and returns first index with that value, -1 if not found

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  
  
public class BooleanFindMethodExample1 {  
    public static void main(String[] args) {  
        // TODO Auto-generated method stub  
        Pattern p=Pattern.compile("java");  
        Matcher m=p.matcher("HellojavaHellojava");  
        int c=0;  
        // finding matching char   
        while(m.find())  
        {  
        c=c+1;  
        System.out.println("Start position of matching String "+m.start());  
        System.out.println("End position of Matching String (java) "+m.end());  
        }  
        System.out.println(" Number of matches : "+c);  
    }  
}
1
2
3
4
5
6
7
8
9
10
11
Pattern pat = Pattern.compile("์—ฌ๊ธฐ์— ์ •๊ทœ์‹ ์ž…๋ ฅ"); 
ํŒจํ„ด์„ ์ •์˜ ํ•œ ํ›„

Matcher match = pat.matcher("์—ฌ๊ธฐ์— ์กฐ์‚ฌํ•  ๋ฌธ์ž์—ด");
์ •์˜๋œ ํŒจํ„ด์— ๋งค์น˜ ๋˜๋Š” ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค.

match.find()
๋งค์น˜๋œ ๊ฐ’์ด ์žˆ์œผ๋ฉด true ์—†์œผ๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

match.group()
๋งค์น˜๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

โžก๏ธ resize(new_capacity) // private ํ•จ์ˆ˜

  • ์šฉ๋Ÿ‰์ด ๊ฝ‰ ์ฐจ๋ฉด, ๊ทธ ๋‘๋ฐฐ๋กœ ํฌ๊ธฐ๋ฅผ ์กฐ์ •ํ•œ๋‹ค.
  • item์„ ํ•˜๋‚˜ ๊บผ๋‚ผ ๋•Œ, ์šฉ๋Ÿ‰์ด 1/4์ด๋ผ๋ฉด, ์šฉ๋Ÿ‰์„ ์ ˆ๋ฐ˜์œผ๋กœ ์ค„์ธ๋‹ค.

๐Ÿซง ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ

: ์ฐจ๋ก€๋กœ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋ฅผ ํ‘œํ˜„ํ•ด์ฃผ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ

๋‹จ) ๋ฐฐ์—ด๊ณผ ๋‹ฌ๋ฆฌ ํŠน์ • ์ธ๋ฑ์Šค๋ฅผ ์ƒ์ˆ˜ ์‹œ๊ฐ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค

(k๋ฒˆ์งธ ์›์†Œ๋ฅผ ์ฐพ๊ณ ์‹ถ๋‹ค๋ฉด ์ฒ˜์Œ๋ถ€ํ„ฐ k๋ฒˆ ๋ฃจํ”„ ๋Œ์•„์•ผํ•จ)

์žฅ) ๋ฆฌ์ŠคํŠธ์˜ ์‹œ์ž‘ ์ง€์ ์—์„œ ์•„์ดํ…œ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œ ์—ฐ์‚ฐ์„ ์ƒ์ˆ˜ ์‹œ๊ฐ„์— ํ•  ์ˆ˜ ์žˆ๋‹ค

  • ๋‹จ๋ฐฉํ–ฅ

    4.png

    • ๊ฐ ๋…ธ๋“œ๋Š” ๋‹ค์Œ ๋…ธ๋“œ ๊ฐ€๋ฆฌํ‚ด
  • ์–‘๋ฐฉํ–ฅ

    5.png

    • ๊ฐ ๋…ธ๋“œ๋Š” ๋‹ค์Œ ๋…ธ๋“œ์™€ ์ด์ „ ๋…ธ๋“œ๋ฅผ ํ•จ๊ป˜ ๊ฐ€๋ฆฌํ‚ด

๐Ÿ’– (๋‹จ๋ฐฉํ–ฅ) ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Node {
	Node next = null;
	int data;
	public Node(int d) {
		data = d;
	}

	void appendToTail(int d) {
		Node end = new Node(d);
		Node n = this;
		while (n.next != null) {
			n = n.next;
		{
		n.next = end;
	}
}

๐Ÿ’– (๋‹จ๋ฐฉํ–ฅ) ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ์‚ญ์ œ

1) ๋…ธ๋“œ n ์ด ์ฃผ์–ด์ง€๋ฉด, ์ด์ „ ๋…ธ๋“œ prev ๋ฅผ ์ฐพ์•„ prev.next ์™€ n.next ๊ฐ€ ๊ฐ™๋„๋ก ์„ค์ •ํ•œ๋‹ค

  • ์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์ผ ๊ฒฝ์šฐ, n.next๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋…ธ๋“œ๋ฅผ ๊ฐฑ์‹ ํ•˜์—ฌ n.next.prev ๊ฐ€ n.prev ๊ฐ€ ๊ฐ™๋„๋ก ์„ค์ •

๐Ÿ’ฅ ์ฃผ์˜

  • ๋„ ํฌ์ธํŠธ ๊ฒ€์‚ฌ๋ฅผ ๋ฐ˜๋“œ์‹œ ํ•œ๋‹ค
  • head์™€ tail ํฌ์ธํ„ฐ๋ฅผ ๊ฐฑ์‹ ํ•œ๋‹ค
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Node deleteNode(Node head, int d) {
	Node n = head;
	if (n.data == d) {
		return head.next;    // head ์›€์ง์ด๊ธฐ
	}

	while (n.next != null) {
		if (n.next.data == d) {
			n.next = n.next.next;
			return head;     // head ์›€์ง์ด์ง€ ์•Š์Œ
		}
	}
	return head;
}
	
๐Ÿ’– Runner (๋ถ€๊ฐ€ ํฌ์ธํ„ฐ)

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•  ๋•Œ ๋‘ ๊ฐœ์˜ ํฌ์ธํ„ฐ๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ

ํ•œ ํฌ์ธํ„ฐ๊ฐ€ ๋‹ค๋ฅธ ํฌ์ธํ„ฐ๋ณด๋‹ค ์•ž์„œ๋„๋ก ํ•œ๋‹ค

  • ์•ž์„  ํฌ์ธํ„ฐ๋Š” ๋’ค ํฌ์ธํ„ฐ๋ณด๋‹ค ํ•ญ์ƒ ์ง€์ •๋œ ๊ฐœ์ˆ˜๋งŒํผ์€ ์•ž์„ค ์ˆ˜ ์žˆ๋‹ค
  • ๋’ค ํฌ์ธํ„ฐ๋ฅผ ์—ฌ๋Ÿฌ ๋…ธ๋“œ๋ฅผ ํ•œ๋ฒˆ์— ๋›ฐ์–ด๋„˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค
๐Ÿ’– ์žฌ๊ท€ ๋ฌธ์ œ

์žฌ๊ท€ ํ˜ธ์ถœ ๊นŠ์ด๊ฐ€ n์ผ ๊ฒฝ์šฐ, ํ•ด๋‹น ์žฌ๊ท€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ ์–ด๋„ O(n) ์˜ ๊ณต๊ฐ„์„ ์‚ฌ์šฉ

๐Ÿซง ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ ๊ตฌํ˜„ํ•˜๊ธฐ

โžก๏ธ size() - ๋ฆฌ์ŠคํŠธ ์•ˆ์˜ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

1
2
LinkedList<Integer> list = new LinkedList<Integer>(Arrays.asList(1,2,3));
System.out.println(list.size()); //list ํฌ๊ธฐ : 3

โžก๏ธ empty() - ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด์žˆ๋‹ค๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

1
2
3
4
5
// ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ๋Š”๊ฐ€
template <typename E>
bool SLinkedList<E>::empty() const{
    return head == NULL;
}

โžก๏ธ value_at(index) - index๋ฒˆ์งธ ์œ„์น˜์˜ value์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. (๊ฐ€์žฅ ์•ž์€ 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค.)

1
2
3
4
5
# declaring array
a = [18, 22, 33, nil, 5, 6]

puts "values_at() method form : #{a.values_at(2, 4)}\n\n"
// values_at() method form : [33, 5]

โžก๏ธ push_front(value) - ๊ฐ€์žฅ ์•ž์— value๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

1
2
3
4
5
int main(void) {
	list<int> L = { 3, 7 };
	L.push_front(1); // { 1, 3, 7 }
	return 0;
}

โžก๏ธ pop_front() - ๊ฐ€์žฅ ์•ž์— ์žˆ๋Š” ๊ฒƒ์„ ์ œ๊ฑฐํ•˜๊ณ , ๊ทธ value๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

1
2
3
4
5
int main(void) {
	list<int> L = { 1, 5, 3, 7, 10 }   
	L.pop_front(); // { 5, 3, 7, 10 }
	return 0;
}

โžก๏ธ push_back(value) - ๊ฐ€์žฅ ๋์— value์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

1
2
3
4
5
int main(void) {
	list<int> L = { 3, 7 };
	L.push_back(10); // { 3, 7, 10 }
	return 0;
}

โžก๏ธ pop_back() - ๊ฐ€์žฅ ๋์— ์žˆ๋Š” ๊ฒƒ์„ ์ œ๊ฑฐํ•˜๊ณ , ๊ทธ value๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

1
2
3
4
5
int main(void) {
	list<int> L = { 1, 5, 3, 7, 10 }   
	L.pop_back(); // { 5, 3, 7, 10}
	return 0;
}

โžก๏ธ front() - ๊ฐ€์žฅ ์•ž์— ์žˆ๋Š” ๊ฒƒ์˜ value๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

1
2
3
4
5
6
7
class CircleList{
public:
    CircleList(); // ์ƒ์„ฑ์ž
    ~CircleList(); // ์†Œ๋ฉธ์ž

    const string& front() const; // ์ปค์„œ ๋‹ค์Œ์˜ ์›์†Œ
};

โžก๏ธ back() - ๊ฐ€์žฅ ๋์— ์žˆ๋Š” ๊ฒƒ์˜ value๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

1
2
3
4
5
6
7
8
class CircleList{
public:
    CircleList(); // ์ƒ์„ฑ์ž
    ~CircleList(); // ์†Œ๋ฉธ์ž

    const string& back() const; // ์ปค์„œ์˜ ์›์†Œ

};

โžก๏ธ insert(index, value) - index๋ฒˆ์งธ ์œ„์น˜์— value๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ฆ‰, index๋ฒˆ์งธ์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๊ฒƒ์ด ๊ธฐ์กด์˜ index๋ฒˆ์งธ์— ์žˆ๋˜ ๊ฒƒ์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

1
2
list<int>::iterator iterInsertPos = list1.begin();
list1.insert(iterInsertsPos, 100);    // ์ฒซ ๋ฒˆ์งธ ์œ„์น˜์— 100 ๋„ฃ๊ธฐ

โžก๏ธ erase(index) - index๋ฒˆ์งธ์— ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•œ๋‹ค.

1
list1.erase(list1.begin());    // list1 ์ฒซ ๋ฒˆ ์งธ ์š”์†Œ ์‚ญ์ œ

โžก๏ธ value_n_from_end(n) - ๋’ค์—์„œ๋ถ€ํ„ฐ n๋ฒˆ์งธ์— ์žˆ๋Š” ๋…ธ๋“œ์˜ value๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

โžก๏ธ reverse() - ๋ฆฌ์ŠคํŠธ๋ฅผ ๋’ค์ง‘๋Š”๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class UnitTest {
    public static void main(String[] args) {
        SinglyLinkedList list = new SinglyLinkedList();
        list.addLast(1);
        list.addLast(2);
        list.addLast(3);
        list.addLast(4);

        System.out.println(list);
        list.reverse();

        System.out.println(list);
    }
}

// 1 -> 2 -> 3 -> 4
// 4 -> 3 -> 2 -> 1

โžก๏ธ remove_value(value) - value์™€ ๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์ง€๋Š” ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.

๐Ÿซง ์Šคํƒ

: ๋ฐ์ดํ„ฐ๋ฅผ ์Œ“์•„ ์˜ฌ๋ฆฐ๋‹ค

LIFO (Last In First Out) ์— ๋”ฐ๋ผ ์ž๋ฃŒ๋ฅผ ๋ฐฐ์—ดํ•œ๋‹ค

๊ฐ€์žฅ ์ตœ๊ทผ์— ์Šคํƒ์— ์ถ”๊ฐ€ํ•œ ํ•ญ๋ชฉ์ด ๊ฐ€์žฅ ๋จผ์ € ์ œ๊ฑฐ๋  ํ•ญ๋ชฉ

๋ฐฐ์—ด๊ณผ ๋‹ฌ๋ฆฌ ์Šคํƒ์€ ์ƒ์ˆ˜ ์‹œ๊ฐ„์— i ๋ฒˆ์งธ ํ•ญ๋ชฉ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Œ

์Šคํƒ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ์—ฐ์‚ฐ์€ ์ƒ์ˆ˜ ์‹œ๊ฐ„์— ๊ฐ€๋Šฅํ•˜๋‹ค

๐Ÿซง ์Šคํƒ์ด ์œ ์šฉํ•  ๊ฒฝ์šฐ

: ์žฌ๊ท€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•  ๋•Œ ์œ ์šฉํ•จ

์žฌ๊ท€์ ์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ์ž„์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์Šคํƒ์— ๋„ฃ์–ด ์ฃผ๊ณ , ์žฌ๊ท€ ํ•จ์ˆ˜๋ฅผ ๋น ์ ธ ๋‚˜์™€ ํ‡ด๊ฐ ๊ฒ€์ƒ‰(backtrack) ํ•  ๋•Œ๋Š” ์Šคํƒ์— ๋„ฃ์–ด ์ฃผ์—ˆ๋˜ ์ž„์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ๋นผ ์ค˜์•ผ ํ•œ๋‹ค

์ผ๋ จ์˜ ํ–‰์œ„๋ฅผ ์ง๊ด€์ ์œผ๋กœ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด ์ค€๋‹ค

์žฌ๊ท€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ฐ˜๋ณต์  ํ˜•ํƒœ (iterative) ๋ฅผ ํ†ตํ•ด์„œ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ

๐Ÿซง ์Šคํƒ ๊ตฌํ˜„ํ•˜๊ธฐ

1
2
3
4
5
6
function Stack(arr = Array()) {
  this.arr = arr;
}

let stk = new Stack();
let stk2 = new Stack(['test', 'test2']);

โžก๏ธ isEmpty() : ๋น„์–ด์žˆ๋Š”์ง€ ํ™•์ธ(๋ฐ˜ํ™˜๊ฐ’ t/f)

1
2
3
Stack.prototype.isEmpty = function(){
  return this.arr.length === 0;
}

โžก๏ธ push(data) : ์Šคํƒ์— ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ํ•˜๊ธฐ

1
2
3
Stack.prototype.push = function (data) {
  this.arr.push(data);
};

โžก๏ธ pop() : ์Šคํƒ ๋งจ ์œ„์˜ ๋ฐ์ดํ„ฐ ์‚ญ์ œํ•˜๊ธฐ

1
2
3
Stack.prototype.pop = function () {
  return this.arr.pop();
};

โžก๏ธ top() : ์Šคํƒ ๋งจ ์œ„์˜ ๋ฐ์ดํ„ฐ ํ™•์ธํ•˜๊ธฐ

1
2
3
Stack.prototype.top = function () {
  return this.arr.slice(-1);
};

โžก๏ธ size() : ์Šคํƒ์˜ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜ ์ถœ๋ ฅ

1
2
3
Stack.prototype.size = function () {
  return this.arr.length;
};

๐Ÿซง ํ

: FIFO (First In First Out) ์ˆœ์„œ

ํ์— ์ €์žฅ๋˜๋Š” ํ•ญ๋ชฉ๋“ค์€ ํ์— ์ถ”๊ฐ€๋˜๋Š” ์ˆœ์„œ๋Œ€๋กœ ์ œ๊ฑฐ๋œ๋‹ค

  • ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰ (bfs)
    • ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ๋…ธ๋“œ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ €์žฅํ•˜๋Š” ์šฉ๋„๋กœ ํ ์‚ฌ์šฉ
    • ๋…ธ๋“œ๋ฅผ ํ•˜๋‚˜ ์ฒ˜๋ฆฌํ•  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ๋…ธ๋“œ์™€ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋“ค์„ ํ์— ๋‹ค์‹œ ์ €์žฅ
    • ๋…ธ๋“œ๋ฅผ ์ ‘๊ทผํ•œ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  • ์บ์‹œ ๊ตฌํ˜„

๐Ÿซง ํ ๊ตฌํ˜„ํ•˜๊ธฐ

๐Ÿ’– tail ํฌ์ธํ„ฐ๊ฐ€ ์žˆ๋Š” ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๊ธฐ

โžก๏ธ enqueue(value) - tail์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ณณ์— value๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค

1
2
3
4
5
6
7
8
9
10
11
int main()
{
    int keys[] = { 1, 2, 3, 4, 5 };
    Queue q;
 
    // ์œ„์˜ ํ‚ค ์‚ฝ์ž…
    for (int key: keys) {
        q.enqueue(key);
    }
    return 0;
}

โžก๏ธ dequeue() - value๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ถ”๊ฐ€๋œ ์›์†Œ(front)๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    int keys[] = { 1, 2, 3, 4, 5 };
    Queue q;
 
    // ์œ„์˜ ํ‚ค ์‚ฝ์ž…
    for (int key: keys) {
        q.enqueue(key);
    }
 
    cout << q.dequeue() << endl;    // 1์„ ์ถœ๋ ฅ
    cout << q.dequeue() << endl;    // 2๋ฅผ ์ถœ๋ ฅ
 
    return 0;
}

โžก๏ธ empty()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <stack>
#include <cstdlib>
using namespace std;
 
// ๋‘ ๊ฐœ์˜ Stack์„ ์‚ฌ์šฉํ•˜์—ฌ Queue ๊ตฌํ˜„
class Queue
{
    stack<int> s1, s2;
 
public:
    // Queue์— ์•„์ดํ…œ ์ถ”๊ฐ€
    void enqueue(int data)
    {
        // ์ฒซ ๋ฒˆ์งธ Stack์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ๋‘ ๋ฒˆ์งธ Stack์œผ๋กœ ์ด๋™
        while (!s1.empty())
        {
            s2.push(s1.top());
            s1.pop();
        }
 
        // ํ•ญ๋ชฉ์„ ์ฒซ ๋ฒˆ์งธ Stack์— ํ‘ธ์‹œ
        s1.push(data);
 
        // ๋ชจ๋“  ์š”์†Œ๋ฅผ ๋‘ ๋ฒˆ์งธ Stack์—์„œ ์ฒซ ๋ฒˆ์งธ Stack์œผ๋กœ ๋‹ค์‹œ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
        while (!s2.empty())
        {
            s1.push(s2.top());
            s2.pop();
        }
    }
 
    // Queue์—์„œ ์•„์ดํ…œ ์ œ๊ฑฐ
    int dequeue()
    {
        // ์ฒซ ๋ฒˆ์งธ Stack์ด ๋น„์–ด ์žˆ๋Š” ๊ฒฝ์šฐ
        if (s1.empty())
        {
            cout << "Underflow!!";
            exit(0);
        }
 
        // ์ฒซ ๋ฒˆ์งธ Stack์˜ ์ตœ์ƒ์œ„ ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
        int top = s1.top();
        s1.pop();
        return top;
    }
};

๐Ÿงก ๊ณ ์ • ๊ธธ์ด ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๊ธฐ

  • enqueue(value) - ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ €์žฅ ๊ณต๊ฐ„์˜ ๋์— item์„ ์ถ”๊ฐ€ํ•œ๋‹ค.
  • dequeue() - value๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ถ”๊ฐ€๋œ ์›์†Œ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.
  • empty()
  • full()

๐Ÿ’› ๋น„์šฉ

  • a bad implementation using linked list where you enqueue at head and dequeue at tail would be O(n) because youโ€™d need the next to last element, causing a full traversal each dequeue
  • enqueue: O(1) (amortized, linked list and array [probing])
  • dequeue: O(1) (linked list and array)
  • empty: O(1) (linked list and array)

๐Ÿซง ํ•ด์‹œํ…Œ์ด๋ธ” (hash table)

: ํšจ์œจ์ ์ธ ํƒ์ƒ‰์„ ์œ„ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๋กœ์„œ, key๋ฅผ value ์— ๋Œ€์‘์‹œํ‚ด

์ตœ์•…์˜ ๊ฒฝ์šฐ O(n) // n์€ ํ‚ค์˜ ๊ฐœ์ˆ˜

์ตœ์„ ์˜ ๊ฒฝ์šฐ O(1)

๐Ÿซง ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์™€ ํ•ด์‹œ ์ฝ”๋“œ ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„

1) ํ‚ค์˜ ํ•ด์‹œ ์ฝ”๋“œ ๊ณ„์‚ฐ

  • ํ‚ค์˜ ์ž๋ฃŒํ˜•์€ ๋ณดํ†ต int or long
  • ํ‚ค์˜ ๊ฐœ์ˆ˜ ๋ฌดํ•œ (int ๋Š” ์œ ํ•œ)

2) hash(key) % array_length ๋ฐฉ์‹์œผ๋กœ ํ•ด์‹œ ์ฝ”๋“œ ์ด์šฉํ•ด ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค ๊ตฌํ•จ

  • ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ ํ•ด์‹œ ์ฝ”๋“œ๊ฐ€ ๊ฐ™์€ ์ธ๋ฑ์Šค ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ์Œ

3) ๋ฐฐ์—ด์˜ ๊ฐ ์ธ๋ฑ์Šค์—๋Š” ํ‚ค์™€ ๊ฐ’์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ์กด์žฌ

  • ํ‚ค์™€ ๊ฐ’์„ ํ•ด๋‹น ์ธ๋ฑ์Šค์— ์ €์žฅ (๋ฐ˜๋“œ์‹œ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ์ด์šฉ!)
  • ๐Ÿ’ฅ ์ถฉ๋Œ : ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ ํ‚ค๊ฐ€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฑฐ๋‚˜, ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ ํ•ด์‹œ ์ฝ”๋“œ๊ฐ€ ๊ฐ™์€ ์ธ๋ฑ์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒฝ์šฐ

โ‡’ ํ‚ค์— ์ƒ์‘ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์œ„๋ฅผ ๋ฐ˜๋ณต!

โ‡’ ์ฃผ์–ด์ง„ ํ‚ค๋กœ๋ถ€ํ„ฐ ํ•ด์‹œ ์ฝ”๋“œ๋ฅผ ๊ณ„์‚ฐ, ํ•ด์‹œ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ด ์ธ๋ฑ์Šค ๊ณ„์‚ฐ, ํ•ด๋‹น ํ‚ค์— ์ƒ์‘ํ•˜๋Š” ๊ฐ’์„ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ ํƒ์ƒ‰

๊ท ํ˜• ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ (balanced binary search tree)
ํƒ์ƒ‰ ์‹œ๊ฐ„์€ O(logN)
ํฌ๊ธฐ๊ฐ€ ํฐ ๋ฐฐ์—ด์„ ๋ฏธ๋ฆฌ ํ• ๋‹นํ•ด ๋†“์ง€ ์•Š์•„๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ ์€ ๊ณต๊ฐ„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

: ํ‚ค์˜ ์ง‘ํ•ฉ์„ ํŠน์ • ์ˆœ์„œ๋Œ€๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅ

๐Ÿซง ํ•ด์‹œํ…Œ์ด๋ธ” ๊ตฌํ˜„ํ•˜๊ธฐ

Linear probing์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐ์—ด๋กœ ๊ตฌํ˜„ํ•ด๋ณด๊ธฐ

1
2
3
4
5
class Node:
    def __init__(self, key, value, next):
        self.key = key
        self.value = value
        self.next = next

โžก๏ธ hash(k, m) - m์€ ํ•ด์‹œ ํ…Œ์ด๋ธ”์˜ ํฌ๊ธฐ

1
2
3
// map์˜ ํฌ๊ธฐ: map.size()
map.size // 4
map.length // undefined

โžก๏ธ add(key, value) - ํ‚ค๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•œ๋‹ค๋ฉด, ๊ฐ’์„ ๊ฐฑ์‹ ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
Hashtable ht = new Hashtable();
ht.Add("irina", "Irina SP");
ht.Add("tom", "Tom Cr");

if (ht.Contains("tom"))
{
    Console.WriteLine(ht["tom"]);
}

โžก๏ธ exists(key)

1
2
3
4
5
6
7
8
map์— ํ•ด๋‹น key์˜ value ์กด์žฌ ์—ฌ๋ถ€: has(key)
map.has(str); // true
map.has(obj); // true
map.has('none'); // falsemap์˜ ํฌ๊ธฐ: map.size()
map.size // 4
map.length // undefinedmap์˜ ํฌ๊ธฐ: map.size()
map.size // 4
map.length // undefined

โžก๏ธ get(key)

  • Map ๊ฐ์ฒด๋Š” key-value๋กœ ์ด๋ฃจ์–ด์ง„ ํ•ด์‹œํ…Œ์ด๋ธ”
    • set(): key-value pair๋ฅผ map์— ์‚ฝ์ž…
    • get(): key๊ฐ’์œผ๋กœ value๋ฅผ ์ฐพ์•„ ๋ฆฌํ„ด
    • key์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์ž๋ฃŒํ˜•์€ number, string, function, object, NaN ๋“ฑ์ด ๊ฐ€๋Šฅ
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
      let number = 0;
      let str = 'string';
      let obj = { a: 1 };
      let func = () => {
          console.log('func');
      };
        
      map.set(number, 4); //key์— number ๊ฐ€๋Šฅ
      map.set(str, 1); // key์— string ๊ฐ€๋Šฅ
      map.set(obj, 2); //key์— object ๊ฐ€๋Šฅ
      map.set(func, 3); // key์— ํ•จ์ˆ˜ ๊ฐ€๋Šฅ
      map.set(number, 0); // ๋ฎ์–ด์“ฐ๊ธฐ ๊ฐ€๋Šฅ
        
      console.log(map); // Map(4) {0 => 0, "string" => 1, {โ€ฆ} => 2, ฦ’unc => 3}
        
      map.get(str); // 1
      map.get(obj); // 2
      map.get('none'); // undefined  
      map.get({ a: 1 }); // undefined, obj !== { a: 1 }
    

โžก๏ธ remove(key)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Collections;
public class SamplesHashtable
{

   public static void Main()
   {
      // Creates and initializes a new Hashtable.
      var myHT = new Hashtable();
      myHT.Add("1a", "The");
      myHT.Add("1b", "quick");

      // Removes the element with the key "3b".
      myHT.Remove("3b");

   }
}
This post is licensed under CC BY 4.0 by the author.