- toc {:toc}
Review
-
κ°μ νμ μ μμ΄ν μ΄ μμλ₯Ό μ§λλ κ·Έλ£Ή. νλμ μ κ΅¬λ‘ λ€μ΄κ°κ³ λμ€λ ꡬ쑰
-
LIFO(Last in First out) ꡬ쑰
-
Queue
-
κ°μ νμ μ μμ΄ν μ μμκ° μλ κ·Έλ£Ή. λ€μμ λ€μ΄κ°κ³ μμΌλ‘ λμ€λ ꡬ쑰
-
FIFO(First in First out) ꡬ쑰
-
List vs Array
-
λ§€μ° μ μ¬νλ, κ°μ κ°λ μ μλλ€.
-
Array : ꡬ체μ μΈ λ°μ΄ν° νμ
- λ€λ₯Έ ADTλ€μ ꡬννλλ° μ¬μ©λ μ μλ€.
-
List : μΆμμ μΈ λ°μ΄ν° νμ (Abstract Data Type, ADT)
- κ°λ μ μΈ λ°μ΄ν° νμ
- arrayλ₯Ό μ¬μ©νμ§ μκ³ κ΅¬νν μ μλ€.
Stack Implementation(Linked List)
-
ADT μ₯μ : ꡬνμ λ°©μμ΄ λ³κ²½λ μ μλ€. ADT κ°λ μ μ ꡬννκΈ°λ§ νλ©΄ λκΈ° λλ¬Έμ΄λ€.
-
μ€νμ λμ λ°°μ΄ κ΅¬νμ λ¨μ - μ€νμ μ΅λ ν¬κΈ°λ₯Ό νλΌλ―Έν°λ‘ μ λ¬λ°μ μμ±λΌμΌ νλ€.
- μ€νμ ν¬κΈ°λ₯Ό μ€κ°μ λμ μΌλ‘ λ³νν μ μλ€.
-
μ€νμ ν¬κΈ°λ₯Ό νλΌλ―Έν°λ‘ λ°μ§ μκ³ push ν λ μ€ν μμμ 곡κ°μ λμ μΌλ‘ ν λΉν μ μλ€.
- μ΄λ»κ²?
- Linked Structure!
-
Operation βnewβ
- free store, heapμ μ΄μ© κ°λ₯νλ€λ©΄ newλ μμ²λ κ°μ²΄λ₯Ό ν λΉνκ³ ν λΉλ μ£Όμλ₯Ό λ°ννλ€.
class StackType{
public:
StackType();
~StackType();
bool IsEmpty();
bool IsFull();
void Push(ItemType item);
void Pop();
ItemType Top();
private:
NodeType* topPtr;
}
struct NodeType{
ItemType info;
NodeType* next;
}
newItem = 'B';
// Push
if (IsFull())
throw FullStack();
NodeType* location;
location = new NodeType<char> // μλ‘ λ€μ΄μ¬ μμΉ λμ ν λΉ
location->info = newItem; // info, nextμ μ 보, μμΉ μ§μ
location->next = topPtr;
topPtr = location; // top location μμ
// Pop
if(IsEmpty())
throw EmptyStack();
else{
NodeType* tempPtr;
tempPtr = topPtr;
topPtr = topPtr->next;
delete tempPtr;
}
// Top
if (IsEmpty())
throw EmptyStack();
else
return topPtr->info;-
Linked List
-
NodeType : κ°μ μ§λ ItemTypeκ³Ό λ€μ NodeTypeμ λνλ΄λ ν¬μΈν°λ₯Ό κ°μ§λ€. β info(data) + next(pointer)
-
Comparing stack implementations
| Operation | Array Implementation | Linked Implementation |
|---|---|---|
| Class constructor | O(1) topμ -1λ‘ μ€μ | O(1) Null NodeType ν¬μΈν° μμ± |
| Make Empty | O(1) Indexλ₯Ό 0μΌλ‘ μ€μ | O(N) μννλ©° ν λΉ ν΄μ |
| IsFull | O(1) top == MaxμΈμ§ νμΈ | O(1) heap λ©λͺ¨λ¦¬ μ€λ₯ νμΈ |
| IsEmpty | O(1) top == 0μΈμ§ νμΈ | O(1) 첫 μμ locationμ΄ NullμΈμ§ νμΈ |
| Push | O(1) 맨 μμ λΆμ¬μ£ΌκΈ° | O(1) μλ‘μ΄ λ Έλ μμ±, top λ Έλλ‘ μ°κ²° |
| Pop | O(1) 맨 μ κ° λΉΌκΈ° | O(1) 맨 μ²μ top κ° λΉΌκΈ° |
| Destructor | O(1) λ°°μ΄ ν λΉ ν΄μ | O(N) μννλ©° ν λΉ ν΄μ |
- Why is a destructor needed? λμ ν λΉ(new)λ₯Ό ν΅ν΄ ν λΉλ heapμ λ©λͺ¨λ¦¬λ main ν¨μκ° λλλλΌλ μλμΌλ‘ ν λΉ ν΄μ λμ§ μλλ€. λͺ μμ μΌλ‘ ν λΉμ ν΄μ ν΄μΌ νλ€. λ§μ½ λͺ μμ μΌλ‘ ν λΉ ν΄μ νμ§ μκ³ ν¨μκ° λλκ² λλ κ²½μ° ν¬μΈν°κ° κ°λ¦¬ν€λ λ Έλλ ν λΉμ΄ λ μ±λ‘ λλΉλλ€.
Queue Implementation(Linked List)
class QueType{
public:
QueType();
~QueType();
bool IsEmpty();
bool IsFull();
void Enqueue(ItemType newItem);
void Dequeue(ItemType& item);
void MakeEmpty();
private:
NodeType<ItemType>* qFront = NULL;
NodeType<ItemType>* qRear = NULL;
}
// Enqueue
NodeType<ItemType>* ptr;
ptr = new NodeType<ItemType>;
ptr->info = newItem;
ptr->next = NULL;
if(qRear == NULL) // νκ° λΉμ΄μμ λ
qFront = ptr; // Front μ€μ
else
qRear->next = ptr; // μ λΉμ΄ μμΌλ©΄ μ΄μ κ°μ λ€μ΄μ¨ κ°κ³Ό μ°κ²°
qRear = ptr; // qRear μμ
// Dequeue
NodeType<ItemType>* tempPtr;
tempPtr = qFront;
item = qFront->info;
qFront = qFront->next;
if(qFront == NULL)
qRear = NULL;
delete tempPtr;
- Comparing queue implementations
| Operation | Array Implementation | Linked Implementation |
|---|---|---|
| Class constructor | O(1) front, rear, items μ€μ | O(1) front, rear Null μ§μ |
| Make Empty | O(1) front, rear μ΄κΈ°ν | O(N) front == Nullμ΄ λ λκΉμ§ μννλ©° ν΄μ |
| IsFull | O(1) ((rear+1)%max == front) νμΈ | O(1) heap λ©λͺ¨λ¦¬ μ€λ₯ νμΈ |
| IsEmpty | O(1) rear == front νμΈ | O(1) frontκ° NullμΈμ§ νμΈ |
| Enqueue | O(1) rear index μ€μ , μ λ ₯ | O(1) μλ‘μ΄ λ Έλ μμ±, rear λ Έλλ‘ μ°κ²° |
| Dequeue | O(1) front index μ€μ , λ°ν | O(1) front κ° λΉΌκΈ° |
| Destructor | O(1) λ°°μ΄ ν λΉ ν΄μ | O(N) μννλ©° ν λΉ ν΄μ |
Static vs Dynamic
-
λ κ°μ§ λ€λ₯Έ λ§₯λ½μμ dynamic, static μ©μ΄λ₯Ό μ¬μ©νλ€.
-
μ΄ λ μ©μ΄λ₯Ό ꡬλΆν νμκ° μλ€.
-
Memory allocation κ΄μ
- Static memory allocation : new/mallocμ μ¬μ©νμ§ μμ μ§μ λ³μκ° μμ±ν λ©λͺ¨λ¦¬λ stack segmentμ μμΉνκ³ μ μ λ©λͺ¨λ¦¬ ν λΉμ νλ€.
- Dynamic memory allocation : new/mallocμ μ¬μ©νμ¬ μ΄κΈ°νλ λ³μκ° μμ±ν λ©λͺ¨λ¦¬λ heap segmentμ μμΉνκ³ λμ λ©λͺ¨λ¦¬ ν λΉμ νλ€.
-
Data structure κ΄μ
- Static data structure : μλ£ κ΅¬μ‘°μ ν¬κΈ°κ° κ³ μ λμ΄ μλ κ²½μ°
- ex) Array-based stack/queue
- Dynamic data structure : μλ£ κ΅¬μ‘°μ ν¬κΈ°κ° κ³ μ λμ΄ μμ§ μμ κ²½μ° λ³νλ κ²½μ°
- ex) Linked structure-based stack/queue
- Static data structure : μλ£ κ΅¬μ‘°μ ν¬κΈ°κ° κ³ μ λμ΄ μλ κ²½μ°
Unsorted List Implementation(Linked List)
- Unsorted
- InsertItem : μ λ ¬μμ΄ λ§¨ μ²μμ λΆμΈλ€.
- RetrieveItem : μννλ©΄μ κ°μ μ°Ύλλ€.
- DeleteItem : μννλ©° κ°μ μ°Ύκ³ ν λΉ ν΄μ λ₯Ό νκ³ , μ΄μ λ
Έλμ nextκ°μ ν΄μ νλ λ
Έλ λ€μμΌλ‘ μ°κ²°μμΌμ€μΌ νλ€.
- νμ§λ§ λ¨λ°©ν₯ linked listμ΄κΈ° λλ¬Έμ μνλ κ°μ λλ¬νλ κ²½μ° μ΄μ κ°μ μ μ μλ€.
- λλ¬Έμ 2λ¨κ³ μμ μ 보λ₯Ό νμΈνλ λ°©μμ μ¬μ©νλ€.
class UnsortedType{
public :
UnsortedType();
~UnsortedType();
void MakeEmpty();
bool IsFull() const;
int LengthIs() const;
void RetrieveItem(ItemType& item, bool& found);
void InsertItem(ItemType item);
void DeleteItem(ItemType item);
void ResetList();
void GetNextItem(ItemType& item);
private :
NodeType<ItemType>* listData;
int length;
NodeType<ItemType>* currentPos;
} ;
// InsertItem
NodeType<ItemType>* location;
location = new NodeType<ItemType>;
location->info = item;
location->next = listData;
listData = location;
length++;
// RetrieveItem
bool moreToSearch;
NodeType<ItemType>* location;
location = listData;
found = false;
moreToSearch = (location != NULL);
while(moreToSearch && !found){
if(item == location->info){
found = true;
}
else{
location = location->next;
moreToSearch = location != NULL);
}
}
// DeleteItem
NodeType<ItemType>* location = listData;
NodeType<ItemType>* tempLocation;
if(item == listData->info){
tempLocation = location;
listData = listData->next;
}
else{
while(!(item == location->next->info))
location = location->next;
tempLocation = location;
location->next = location->next->next;
}
delete tempLocation;
length--;- Comparison unsorted list implementations
| Operation | Array Implementation | Linked Implementation |
|---|---|---|
| Class constructor | O(1) length μ§μ | O(1) listData = NULL μ§μ |
| Destructor | O(1) λμ ν λΉX | O(N) NULL κΉμ§ μννλ©° ν΄μ |
| MakeEmpty | O(1) length = 0 | O(N) μννλ©° ν΄μ |
| IsFull | O(1) length == MAX νμΈ | O(1) heap λ©λͺ¨λ¦¬ μ€λ₯ λ©μμ§ νμΈ |
| LengthIs | O(1) length λ°ν | O(1) length λ°ν |
| ResetList | O(1) currentPos = -1 | O(1) currentPos = listData |
| GetNextItem | O(1) currentPos++ μΆμΆ | O(1) currentPosβnextβinfo |
| RetrieveNextItem | O(N) or O(logN) νμ νμνκΈ° λλ¬Έ | O(N) μννμ¬ νμ |
| InsertItem | O(1) 맨 λ€μ μ½μ | O(1) 맨 μμ μ½μ |
| DeleteItem | O(N) νμν΄ μ§μ°κ³ λΉμ리 μ΄λμμΌμΌ ν¨ | O(N) νμν΄ μ§μ°κΈ° |
Sorted List Implementation(Linked List)
1 β 3 β 7 β 9
- Sorted
- InsertItem : μμΉλ₯Ό νμνκ³ ν΄λΉ μμΉμ μ½μ ν΄μΌ νλ€. 4λ₯Ό μ½μ νλ κ²½μ° 3κ³Ό 7 μ¬μ΄μ μ½μ ν΄μΌ νκΈ° λλ¬Έμ info == 3μΈ λ Έλμ nextλ₯Ό 4λ‘ μ§μ ν΄μ€μΌ νλ€. Unsortedμ κ°μ΄ 2λ¨κ³ λ€λ₯Ό μκ°νλ λ°©μμ΄ μμΌλ, 10μ μ½μ νλ κ²½μ° μ¦, 맨 λ§μ§λ§μ μ½μ νλ κ²½μ° 2λ¨κ³ λ€μ infoλ₯Ό νμΈνλ λ°©μμ NULLκ°μ λ°κΈ° λλ¬Έμ μ¬μ©ν μ μλ€. λλ¬Έμ ν¬μΈν°λ₯Ό 2κ°λ₯Ό μ¬μ©νμ¬ ν΄κ²°νλ€.
- RetrieveItem : μ΄λ―Έ μ λ ¬λμ΄ μκΈ° λλ¬Έμ itemλ³΄λ€ ν°μ§, μμμ§, κ°μμ§λ₯Ό νλ¨νλ©΄ λλ€. μ΄μ§ νμμ μ¬μ©ν μλ μμΌλ, μ΄μ§ νμμ μ¬μ©νλλΌλ 볡μ‘λκ° O(logN)μ΄ λμ§λ μλλ€.(λ¨λ°©ν₯μ΄λ―λ‘)
class SortedType{
public :
SortedType();
~SortedType();
void MakeEmpty();
bool IsFull() const;
int LengthIs() const;
void RetrieveItem(ItemType& item, bool& found);
void InsertItem(ItemType item);
void DeleteItem(ItemType item);
void ResetList();
void GetNextItem(ItemType& item);
private :
NodeType<ItemType>* listData;
int length;
NodeType<ItemType>* currentPos;
} ;
// RetrieveItem
NodeType<ItemType>* location;
location = listData;
found = false;
while((location!=NULL) && !found){
if (location->info < item)
location = location->next;
else if (location->info == item)
found = true;
else
location = NULL;
}
// InsertItem
bool isFindLoc;
NodeType<ItemType>* predLoc = NULL;
NodeType<ItemType>* location = listData;
NodeType<ItemType>* newNode;
newNode = new NodeType<ItemType>;
newNode->info = item;
if(listData == NULL){
newNode->next = NULL;
listData = newNode;
length++;
}
else{
while (true){ // for searching.
if(predLoc == NULL) // Add item at the first index.
isFindLoc = (item <= location->info);
else if(location == NULL) // Add item at the last index.
isFindLoc = (item >= predLoc->info);
else
isFindLoc = (predLoc->info <= item && item <= location->info);
if(isFindLoc){
newNode->next = location;
length++;
if(predLoc == NULL){
listData = newNode;
break;
}
predLoc->next = newNode;
break;
}
else{
predLoc = location;
location = location->next;
}
}
}- Comparing sorted list implementations
| Operation | Array Implementation | Linked Implementation |
|---|---|---|
| Class constructor | O(1) length μ§μ | O(1) listData = NULL μ§μ |
| Destructor | O(1) λμ ν λΉX | O(N) NULL κΉμ§ μννλ©° ν΄μ |
| MakeEmpty | O(1) length = 0 | O(N) μννλ©° ν΄μ |
| IsFull | O(1) length == MAX νμΈ | O(1) heap λ©λͺ¨λ¦¬ μ€λ₯ λ©μμ§ νμΈ |
| LengthIs | O(1) length λ°ν | O(1) length λ°ν |
| ResetList | O(1) currentPos = -1 | O(1) currentPos = listData |
| GetNextItem | O(1) currentPos++ μΆμΆ | O(1) currentPosβnextβinfo |
| RetrieveNextItem | O(N) or O(logN) νμ νμνκΈ° λλ¬Έ | O(N) μννμ¬ νμ |
| InsertItem | O(N) μννμ¬ μμΉ νμ, μ리 μ΄λ, μ½μ | O(N) μννμ¬ μ½μ |
| DeleteItem | O(N) νμν΄ μ§μ°κ³ λΉμ리 μ΄λμμΌμΌ ν¨ | O(N) νμν΄ μ§μ°κΈ° |