List

2020. 9. 15. 04:45컴퓨터 수업/자료구조

@Category

-List의 정의

-List의 종류

-ADT와 List, 그 opeartion과 domain

-UnsortedType

-SortedType

-Big (o) 정도...?

 

@List의 정의

리스트의 필수요소로 리스트의 정의를 설명하자면,

 

Linear relationship을 가져야한다.

 

Linear relationship =

Each element except the first has a unique predecessor, and each element except the last has unique successor

 

@List의 종류

Unsorted List와 Sorted List가 있다.

 

1. Unsorted List

리스트 상의 데이터에 순서가 없다. 그 순서는 alphabetical이 될 수도 있고, numerical 하게 increasing order or decreasing order가 될 수도 잇다.

 

2. Sorted List

리스트 상의 데이터에 순서가 있다.

 

@ADT와 리스트, 그 operation과 domain

ADT와 리스트가 무슨 관계를 가질까?

 

여러 자료구조 중에서 어떤 리스트가 있다고 가정해보자 , User는 이 리스트의 모든것을 알 필요는 없다.

 

따라서, 추상화하여 abstract한 class로 작성한다. 이를 Abstract data type이라 한다.

 

그렇다면 이 class에는 prototype만 declaration 한다는 것인데,

 

어떤 domain과 operation을 선언해야 할까?

1.operation의 종류

#Constructor

#Transformer

#Observer

#Iterator

 

각각의 method를 소개하기전에 각각의 분류에 어떤 메소드(operation)가 들어가야 할 지 고민해보자.

 

#Constructor

생성자, 무엇을 생성하는것일까?

바로 이 자료형, List를 생성하는것이다.

아규먼트가 주어지지 않는다면 기본생성자로 모든 data가 Null하게 생성할수도 있겠다.

또한, 주어진 boolean인자로 boolean이 0이라면 위에서 설명한것과 같이 Null하게, 1이라면 모든 data를 RAND함수를 호출하여 랜덤하게 집어넣을 수 도 있겠다. 그저 생성자가 List의 data를 초기화 한다는 생각이 들면 ok

list();

 

#Transformer

List를 변화시키는게 무엇이 있을까? 당연히 값을 집어넣거나 빼는것이다.

그런데 그 내부를 고민해보면, 값을 집어넣거나 빼는 방식에도 차이가 있다.

일단 집어넣는것은 static한 list에 맨 마지막이나 맨 앞에 집어넣어야한다.(Unsorted의 경우)

그리고 빼는것은 그 자리를 그저 빈공간으로도 둘 수 있지만, 빈 공간으로 두지않고, list의 형태를 유지할 수 있도록

그 자리를 비우고, last의 data를 그 자리로 가져올 수 있다.

void DeleteItem(arguments);
void InsertItem(arguments);

#Observer

지금 list의 length가 얼마나 될까?

지금 list가 꽉 찼을까?

어떤 특정 index의 data 값이 내가 argument로 넣은 data 값과 같은가?

bool IsFull(arguments);
int LengthIs(arguments);
int(class) RetriveItem(arguments);
(특정 index의 data값이 무엇인가? -> 이게 왜 없는지는 다음과 같이 생각해 볼 수 있다.)

밑의 iterator를 봐도 알겠지만, User는 list의 특정 index에 접근할 수 없고, 특정 index가 있는지조차

알 수 없게 해야한다. 따라서 3번부터 5번의 data를 불러오고자 하는 행위는 애초에 성립할 수가 없다.

따라서 0번부터 3번의 list data를 불러올려면

for(int i=0;i<3;i++)

getItem(i); 가 아닌

for(int i=0;i<3;i++)

getitem(); 인 것이다.

#Iterator

인덱스에 접근할 수 없으니,

position을 가장 앞으로 옮기는 함수와, 순차적으로 값을 반환하는 함수가 있을 수 있겠다.

void ResetList();
void GetNextItem(ItemType& item);

나도 안다, 뭔가 찜찜하게, 있어야 할 함수가 없는것처럼 보이기도하고, 이 함수가 굳이 필요한가 싶기도 한 이 기분...

하지만 Abstract하게 User에게 편의성을 제공해주는 측면에서 내가 생각한것보다 남이 생각한것이 맞다고 가정한다면

위의 구성요소를 조금은 외울 필요가 있다.

Constructor는 그 자체이고, Observer로는 isfull, lengthis, retriveitem(일치여부), Transformer로는 insert,delete, #iterator로는 reset,getnext 가 있다는것을 1 3 2 2로 기억해두자.

 

2. Domain의 종류

length, currentPos, info[MAX_ITEMS] 가 있겠다. (요것도 좀 외우자.)

 

이쯤에서 generic data type에 대해서 알고 가야한다.

리스트에 들어가있는 datatype은 int일까? 혹은 char일까? 이를 모르기에 class로 composite data type을 작성한다.

그리고 이 class와 다른 class의 대소비교는 그 안의 내부 data를 모르면 불가능하기에, 그 private한 data에 접근할 수 있도록 이 class의 내부에 compareTo를 작성하여 비교한다.

(CompareTo 메소드는 ItemType 내부에!)

 

@UnsortedType

#Abstract Data Type "UnsortedType"

#pragma once
#include "ItemType.h"
class UnsortedType
{
public:
	//constructor
	UnsortedType();
	//Transformer
	void InsertItem(const ItemType& item);
	void DeleteItem(const ItemType& item);
	//Observer
	bool IsFull() const;
	int LengthIs() const;
	bool RetriveItem(const ItemType& item);
	//Iterator
	void ResetList();
	const ItemType& GetNextItem();
private:
	int length;
	int currentPos;
	ItemType info[MAX_ITEMS];
};

#Encapsulated generic data type "ItemType" (not abstract)

#pragma once
#define MAX_ITEMS 5
enum RelationType
{
	LESS,
	GREATER,
	EQUAL
};
class ItemType
{
public:
	RelationType ComparedTo(const ItemType&) const;
	void Print() const;
	void Initialize(int number);
private:
	int value;
};

#Implementation of "UnsortedType"

#include <iostream>
#include "UnsortedType.h"
using namespace std;

//Constructor
UnsortedType::UnsortedType()
//Pre: None.
//Post: List is Empty
{
	length = 0;
}

//Transformer
void UnsortedType::InsertItem(const ItemType& item)
//Pre: List has been initialized. List is not full
//item is not in list
//Post: item is in the list
{
	if (!IsFull())
	{
		info[length - 1] = item;
		length++;
	}
	else
	{
		cout << "List is full to InsertItem !" << endl;
		exit(1);
	}
}
void UnsortedType::DeleteItem(const ItemType& item)
//Pre: item's key has been initialized.
//An element in the list has a key that matches item's
//Post: No element in the list has a key that matches item's
{
	int location = 0;
    
  
	while (item.ComparedTo(info[location]) != EQUAL)
	{
		location++;
	} // location은 지금 현재 compare했을 때, 같은 지점을 가리킴
    
    //내 생각으론, 이렇게 코드를 짜는게 낫다.
	//for (location = 0;location < length;location++)
	//{
	//	if (item.ComparedTo(info[location]) == EQUAL)
	//	{
	//		break;
	//	}
	//}
	//if (location == length)
	//{
	//	cout << "There is no items like that" << endl;
	//	exit(1);
	//}

	info[location] = info[length - 1];
	length--;
	// 현재 List의 Last가 garbage값을 갖고 있을텐데 우짜지

}
//Observer
bool UnsortedType::IsFull() const
//Pre: List has been initialized.
//Post: Function value == (list is full).
{
	return (length == MAX_ITEMS); // 이러한 기법에 주의하자. if를 통해서 bool값을 반환하는 것이 아닌, 방법
}
int UnsortedType::LengthIs() const
{
	return length;
}
bool UnsortedType::RetriveItem(const ItemType& item)
{
	int location = 0;
	//내 생각의 흐름으론 이렇게 짜는게 낫다.
	//for (location = 0;location < length;length++)
	//{
	//	if (item.ComparedTo(info[location]) == EQUAL)
	//		return true;
	//}
	//if (location == length)
	//	return false;
    
    //아래 기법이 textbook의 기법인데, 꽤나 중요해 보인다.
    //판단척도를 여러 객체화하였다.
    
	bool found = false; // 일단은 못 찾았다/
	bool moreToSearch;
	moreToSearch = (location < length);
	while (moreToSearch && !found)
	{
		switch (item.ComparedTo(info[location]))
		{
		case LESS:
		case GREATER:
			location++;
			moreToSearch = (location < length);
			break;
		case EQUAL:
			found = true;
			break;
		}
	}
	return found;
}
//Iterator
void UnsortedType::ResetList()
{
	currentPos = 0;
}
const ItemType& UnsortedType::GetNextItem()
{
	currentPos++;
	return info[currentPos - 1];
 }

Delete와 Insert의 알고리즘을 좀 봐둘 필요가 있다.

UnsortedType에서 delete의 경우는 argument로 주어진 item을 찾아서 빼고, 맨 뒤(last)의 item을 그 자리에 갖다 넣었다.(당연히 length--)Insert의 경우엔 argument로 주어진 item을 그저 맨 뒤에 넣었다. (당연히 length++)

 

@SortedType

ADT나 GDT는 생략하겠다.

딜리트 인서트 리트라이브

#Implementation of "SortedType"

1. Implementation of InsertItem

void SortedType::InsertItem(const ItemType& item)
{
	int location = 0;
	bool moreToSearch = (location < length); // 이 구문을 주의할것. 언제나 true인것은 아니기에
	while (moreToSearch)
	{
		switch (item.ComparedTo(info[location]))
		{
		case LESS:
		case EQUAL:
			moreToSearch = false;
			break;
		case GREATER:
			moreToSearch = location < length;
			location++;
		}
	}
	for (int i = length;i > location;i--)
	{
		info[i] = info[i - 1];
	}
	info[location] = item;
	length++;
}

moreToSearch는 자주 나오는 boolean값이라 생각하자,

while()

{

switch()

}

를 자주 이용한다는 것 또한 기억할것.

인서트 알고리즘은 sorted니까 item이 들어갈 index를 찾고, 그 공간을 한칸씩 뒤로 밀어서 공간을 창출하고,

그 공간에 item을 집어넣는다.

 

2.Implementation of DeleteItem

void SortedType::DeleteItem(const ItemType& item)
{
	int location = 0;
	bool moreToSearch = (location < length);
	while (moreToSearch)
	{
		switch (item.ComparedTo(info[location]))
		{
		case EQUAL:
			moreToSearch = false;
			break;
		case LESS:
		case GREATER:
		default:
			moreToSearch = (location < length);
			location++;
		}
	}

	if (!(location < length))
	{
		cout << "There is no item like this" << endl;
	}
	else
	{
		for (int i = location;i < length-1;i++)
		{
			info[i] = info[i + 1];
		}
		length--;
	}
}

딜리트할 item이 어디있는지 찾고, 그 공간을 비우고, 한칸씩 앞으로 당긴다.

 

3.Implementation of RetriveItem by binary search

bool SortedType::RetriveItem(const ItemType& item) const
{
	int midpoint;
	int first = 0;
	int last = length - 1;
	bool moreToSearch = (first <= last);
	bool found = false;
	while (moreToSearch && !found)
	{
		midpoint = (first+last)/2;
		switch (item.ComparedTo(info[midpoint]))
		{
		case EQUAL:
			found = true;
			break;
		case LESS:
			last = midpoint - 1;
			moreToSearch = (first <= last);
			break;
		case GREATER:
			first = midpoint + 1;
			moreToSearch = (first <= last);
			break;
		}

		return found;
	}
}

moreToSearch가 first <= last 로 정의되어있는것과, while argument의 &&를 사용한것을 주의한다.

찾거나, 더이상 찾을게 없으면, 이라는 구문이다.

'컴퓨터 수업 > 자료구조' 카테고리의 다른 글

리스트와 스택의 차이  (0) 2020.10.05
Big O notation  (0) 2020.09.15
buffer란?  (0) 2020.09.14
용어  (0) 2020.09.14
ADT (Abstract Data Type)  (0) 2020.09.14