• toc {:toc}

Sorted List using Doubly Linked List

  • 이전 단방ν–₯ linked list μ—μ„œλŠ” NodeType 에 next 만 μ μš©λ˜μ–΄ μžˆλŠ” 반면 doubly linked list λŠ” back, next 2 κ°€μ§€κ°€ μ μš©λ˜μ–΄ 이전 포인터도 μ €μž₯ν•˜λŠ” ꡬ쑰λ₯Ό κ°–λŠ”λ‹€.

FindItem

  • InsertItem, DeleteItem, RetrieveItem λͺ¨λ‘ νŠΉμ • item 을 μ°ΎλŠ” 과정이 ν•„μš”ν•˜κΈ° λ•Œλ¬Έμ— FindItem ν•¨μˆ˜λ₯Ό μ μš©ν•œλ‹€.(return location, found)
  • FindItem precondition : λ¦¬μŠ€νŠΈλŠ” λΉ„μ–΄μžˆμ§€ μ•ŠλŠ”λ‹€.
template<class ItemType>
void FindItem(NodeType<ItemType>* listData, ItemType item,
	NodeType<ItemType>* &location, bool &found){
 
	bool moreToSearch = true;
	location = listData;
	found = false;
 
	while(moreToSearch && !found){
		if(item < location->info)
			moreToSearch = false;
		else if(item == location->info)
			found = true;
		else{
			// location = location->next   맨 끝에 λ‘˜ 수 없기에 μ•„λž˜λ‘œ λ³€κ²½
			// moreToSearch = location!=NULL;
			if(location->next == NULL)
				moreToSearch = false;
			else
				location = location->next;
		}
	}
}
  • μˆœνšŒν•˜λ©° item 보닀 μž‘λ‹€λ©΄ λ‹€μŒμœΌλ‘œ, κ°™λ‹€λ©΄ found flag λ₯Ό ν†΅ν•΄μ„œ while λ¬Έ νƒˆμΆœ
  • μ •λ ¬λ˜μ–΄ μžˆλŠ” μƒνƒœμ΄κΈ° λ•Œλ¬Έμ— item 보닀 μˆœνšŒν•˜λŠ” 값이 더 크닀면 item 에 λ§žλŠ” 값이 μ—†λŠ” κ²ƒμ΄λ―€λ‘œ 탐색할 ν•„μš”κ°€ μ—†λ‹€.
  • location, found λŠ” &둜 λ°›μ•„ pass by reference 둜 ν•¨μˆ˜ μ•ˆμ—μ„œ μ§€μ •λ˜λŠ” 값을 κ·ΈλŒ€λ‘œ λ°›μ•„μ˜¬ 수 μžˆλ„λ‘ ν•œλ‹€.

InsertItem

template<class ItemType>
void InsertItem(ItemType item){
	NodeType<ItemType>* newNode;
	NodeType<ItemType>* location;
    bool = found;
 
    newNode = new NodeType<ItemType>;
    newNode->info = item;
    if(listData != NULL){   // listκ°€ μ°¨ μžˆλŠ” 경우
        FindItem(listData, item, location, found);
        if(location->info > item){  // item이 쀑간에 μœ„μΉ˜ν•œ 경우
            newNode->back = location->back;
            newNode->next = location;
            if(location != listData){       
                location->back->next = newNode;
            }
            location->back = newNode;
        }
        else{       // item이 end에 μœ„μΉ˜ν•œ 경우
            newNode->back = location;
            location->next = newNode;
            newNode->next = NULL;
        }
    }
    else{           // listκ°€ 빈 경우
        listData = newNode;
        newNode->next = NULL;
        newNode->back = NULL;
    }
    length++;
}
  • 이전, λ‹€μŒ λ…Έλ“œλ₯Ό κ°€λ¦¬ν‚€λŠ” 포인터λ₯Ό λ³€κ²½ν•  λ•Œ λ³΄μœ ν•œ 값이 사라지지 μ•Šλ„λ‘ μˆœμ„œμ— μœ μ˜ν•΄μ•Ό ν•œλ‹€.
    • newNodeβ†’back = locationβ†’back μš°μ„ 
    • locationβ†’back = newNode λ‹€μŒ

Headers and Trailers

  • μ‹œμž‘, 끝 μ§€μ μ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν•˜κΈ° λ•Œλ¬Έμ— Header 와 Trailer λ₯Ό μ‚¬μš©ν•΄μ„œ μ˜ˆμ™Έλ₯Ό λ°°μ œν•˜λŠ” 방식을 μ‚¬μš©ν•˜κΈ°λ„ ν•œλ‹€.
  • Idea : 리슀트의 μ–‘ 끝 단에 μ ˆλŒ€ μ‚½μž…, μ‚­μ œλ₯Ό ν•˜μ§€ μ•Šλ„λ‘ λ§Œλ“ λ‹€.
  • Method : μ–‘ 끝 단에 κ°€λŠ₯ν•œ κ°’μ˜ λ²”μœ„λ₯Ό μ΄ˆκ³Όν•œ dummy λ…Έλ“œλ₯Ό λ§Œλ“ λ‹€.
  • Header : κ°€λŠ₯ν•œ 리슀트 값보닀 더 μž‘μ€ 값을 ν¬ν•¨ν•œλ‹€.
  • Trailer : κ°€λŠ₯ν•œ 리슀트 값보닀 더 큰 값을 ν¬ν•¨ν•œλ‹€.

Shallow Copy / Deep Copy

  • Shallow Copy : 클래슀 멀버 λ°μ΄ν„°λ§Œ λ³΅μ‚¬ν•˜κ³ , 가리킀고 μžˆλŠ” λ°μ΄ν„°λŠ” λ³΅μ‚¬ν•˜μ§€ μ•ŠλŠ”λ‹€. 즉, 가리킀고 μžˆλŠ” λ°μ΄ν„°λŠ” 본래 클래슀 객체와 κ³΅μœ ν•œλ‹€.
  • Deep Copy : 클래슀 멀버 데이터 뿐만 μ•„λ‹ˆλΌ 가리킀고 μžˆλŠ” 데이터도 λ”°λ‘œ μ €μž₯ν•œλ‹€. 본래 클래슀 객체의 λ°μ΄ν„°μ˜ μœ„μΉ˜μ™€ λ‹€λ₯Έ 곳에 데이터λ₯Ό μ €μž₯ν•˜κ³  가리킨닀.

image

Shallow Copy

  • λ‹€μŒμ˜ 경우 μ–΄λ–»κ²Œ 될까?
void Func(StackType<ItemType> SomeStack){
	ItemType item;
	SomeStack.Pop(item);
}
 
// main
StackType<int> MyStack;
Func(MyStack);
  • Func 의 νŒŒλΌλ―Έν„°λ‘œ μ „λ‹¬λœ μŠ€νƒμ€ pass by value 둜 전달됐닀.
  • λ‹€μŒμ˜ κ²½μš°μ—λŠ” Shallow Copy κ°€ μ μš©λœλ‹€.

image

  • κ²°κ³ΌλŠ” μœ„ κ·Έλ¦Όκ³Ό κ°™λ‹€.
  • μˆœμ„œ
  1. MyStack 을 전달해 SomeStack 으둜 Shallow Copy λ₯Ό ν•œλ‹€.
  2. μ΄λ•Œ SomeStack 의 top 은 MyStack κ³Ό 같은 μœ„μΉ˜μ˜ 값을 가리킨닀.
  3. μ΄λ•Œ SomeStack.Pop(item) 으둜 인해 SomeStack 은 Pop 을 ν•˜κ³  6000 의 μ£Όμ†Œκ°’μ„ 가리킨닀.
  4. ν•˜μ§€λ§Œ, MyStack 의 경우 μ—¬μ „νžˆ 7000 μ£Όμ†Œκ°’μ„ 가리킀고 있게 λœλ‹€.

Deep Copy

  • κΈ°λ³Έ μƒμ„±μžλ₯Ό μ‚¬μš©ν•  경우 pass by value 둜 μƒμ„±λœλ‹€.
  • 포인터가 동적 데이터λ₯Ό 가리킬 λ•Œ pass by value 즉, Shallow Copy 의 경우 포인터가 κ°€λ¦¬ν‚€λŠ” 값을 λ³΅μ‚¬ν•˜μ§€ λͺ»ν•˜λ―€λ‘œ μœ„μ™€ 같은 λ¬Έμ œκ°€ λ°œμƒν•œλ‹€.
  • λ‹€λ₯Έ λ©”λͺ¨λ¦¬ κ³΅κ°„μ—μ„œ 동적 λ°μ΄ν„°μ˜ Deep Copy λ₯Ό λ§Œλ“œλŠ” copy constructor λ₯Ό ν΄λž˜μŠ€μ— λ§Œλ“€μ–΄ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.
  • Copy constructor
    • Pass by reference λ₯Ό μ‚¬μš©ν•œλ‹€.
    • Copy constructor λ₯Ό λ§Œλ“€μ–΄ λ‘” 경우, pass by value 둜 볡사λ₯Ό ν•˜λ”λΌλ„ μ•”λ¬΅μ μœΌλ‘œ copy constructor κ°€ ν˜ΈμΆœλ˜μ–΄ λ³΅μ‚¬λœλ‹€.
template<class ItemType>
class StackType{
public:
	StackType(){
		cout << "Default Constructor" << endl;
	};
	StackType(const StackType<ItemType>& anotherStack);
	// Copy constructor
	{
		cout << "Copy Constructor" << endl;
		.
		.
		.
	}
	~StackType();
private:
	NodeType<ItemType>* topPtr;
}
 
int main(){
	StackType<int> SomeStack;
	SomeStack.Push(1);
	StackType<int> AnotherStack(SomeStack);
}
 
// Result
// Default Constructor
// Copy Constructor
  • μ™œ νŒŒλΌλ―Έν„°λ₯Ό const 둜 μ§€μ •ν• κΉŒ?
  • const 둜 νŒŒλΌλ―Έν„°λ₯Ό μ§€μ •ν•˜λ©΄ ν•΄λ‹Ή νŒŒλΌλ―Έν„°λŠ” λ³€ν˜•μ„ κ°€ν•  수 μ—†λ‹€.
  • ν•˜μ§€λ§Œ copy constructor 의 경우 값을 λ³€ν™”μ‹œν‚€μ§€ μ•Šκ³  볡사λ₯Ό ν•˜λŠ” 역할을 ν•˜κΈ° λ•Œλ¬Έμ— const 둜 λͺ…ν™•ν•˜κ²Œ λͺ…μ‹œν•œλ‹€.
  • Copy constructor λŠ” λ‹€μŒμ˜ 3 κ°€μ§€ μƒν™©μ—μ„œ μ•”λ¬΅μ μœΌλ‘œ ν˜ΈμΆœλ˜λŠ” νŠΉμˆ˜ν•œ 멀버 ν•¨μˆ˜μ΄λ‹€.
    • 객체 νŒŒλΌλ―Έν„°λ₯Ό value 둜 μ „λ‹¬ν•˜λŠ” 경우
    • μ„ μ–Έμ—μ„œ 객체 λ³€μˆ˜λ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” 경우
    • ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μœΌλ‘œ 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” 경우

Assignment Operator =

  • λ§Œμ•½, ν΄λž˜μŠ€κ°€ 동적 데이터λ₯Ό κ°€λ¦¬ν‚€λŠ” 데이터 멀버 포인터λ₯Ό κ°€μ§€κ³  μžˆλ‹€λ©΄ 동적 λ°μ΄ν„°μ˜ Deep Copy λ₯Ό λ§Œλ“œλŠ” ν• λ‹Ή μ—°μ‚°μžλ₯Ό μž‘μ„±ν•΄μ•Ό ν•œλ‹€.
template<class ItemType>
class StackType{
public:
	StackType();
	StackType(const StackType<ItemType>& anotherStack);
	// Copy constructor
	void operator= (const StackType<itemType>& originalStack);
	~StackType();
private:
	NodeType<ItemType>* topPtr;
}