Transcript 배열과연결리스트
13일째 배열과 연결리스트
배열과 연결 리스트
- 배열이란? 배열의 선언?
- 배열과 포인터의 관계?
-문자열이란? 문자배열
- 연결 리스트
1
13일째 배열과 연결리스트
배열이란
배열
동일한 자료형을 저장하는 장소들의 모임
배열의 선언
형 배열의이름 [항의개수] ;
long LongArray[25] ;
배열의 원소
배열내의 각각의 저장 장소
변위(offset)을 지정하여 접근
LongArray[0] ~ LongArray[24]
배열의 끝을 지나 값을 저장할 경우
항의 존재 유무를 검사하지 않는다
“offset X 각 원소의 크기” 위치에 무조건 저장
2
13일째 배열과 연결리스트
#include <iostream>
using namespace std;
list 13.2
int main()
{
long sentinelOne[3];
long TargetArray[25];
long sentinelTwo[3];
for (int i=0; i<3; i++)
sentinelOne[i] = sentinelTwo[i] = 0;
for (i=0; i<25; i++)
TargetArray[i] = 0;
cout <<"Test 1: \n";
cout <<"TargetArray[0]: "<<TargetArray[0] << "\n";
cout <<"TargetArray[24]: “<<TargetArray[24]<<"\n\n";
for (i = 0; i<3; i++)
{
cout << "sentinelOne[" << i << "]: ";
cout << sentinelOne[i] << "\n";
cout << "sentinelTwo[" << i << "]: ";
cout << sentinelTwo[i]<< "\n";
}
3
13일째 배열과 연결리스트
cout << "\nAssigning...";
for (i = 0; i<=25; i++)
TargetArray[i] = 20;
cout << "\nTest 2: \n";
cout << "TargetArray[0]: "
<< TargetArray[0] << "\n";
cout << "TargetArray[24]: "
<< TargetArray[24] << "\n";
cout << "TargetArray[25]: "
<< TargetArray[25] << "\n\n";
for (i = 0; i<3; i++)
{
cout << "sentinelOne[" << i << "]: ";
cout << sentinelOne[i]<< "\n";
cout << "sentinelTwo[" << i << "]: ";
cout << sentinelTwo[i]<< "\n";
}
return 0;
}
4
13일째 배열과 연결리스트
배열의 초기화
배열의 초기화
={쉼표로 분리된 초기값들}
int IntegerArrary[5] = { 10, 20, 30, 40, 50 } ;
int IntegerArrary[5] = { 10, 20, 30, 40, 50, 60 } ;
(X)
int IntegerArrary[5] = { 10, 20} ;
(O)
int IntegerArrary[ ] = { 10, 20, 30, 40, 50 } ;
array 크기 = sizeof( IntegerArray )
/ sizeof( IntegerArray[0] ) ;
5
13일째 배열과 연결리스트
기타
배열명
같은 범위 내에서 같은 변수명이나 배열명과
겹쳐서는 안됨
배열명은 배열을 가지고 있는 메모리의 주소
( 제일 첫번째 원소의 주소 )
배열의 차원
상수형 또는 나열형
변위는 변수가 가능하나 선언 시 배열의 크기는
변수가 되어서는 안됨
(사용자 정의)객체의 배열
모든 객체(내장+사용자 정의)는 배열에 저장 가능
6
13일째 배열과 연결리스트
#include <iostream>
using namespace std;
class CAT
{
public:
CAT() { itsAge = 1; itsWeight=5; }
~CAT() {}
int GetAge() const { return itsAge; }
int GetWeight() const { return itsWeight; }
void SetAge(int age) { itsAge = age; }
private:
int itsAge;
int itsWeight;
};
int main()
{
CAT Litter[5];
for (int i = 0; i < 5; i++)
Litter[i].SetAge(2*i +1);
for (i = 0; i < 5; i++){
cout << "Cat #" << i+1<< ": ";
cout << Litter[i].GetAge() << endl;
}
return 0;
}
7
13일째 배열과 연결리스트
다차원 배열
n 차원의 배열은 n개의 첨자를 가짐
형 배열의이름 [항의개수][항의갯수] … [항의개수] ;
n
SQUARE Board[8][8] ;
다차원 배열 초기화
int Array[4][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 } ;
Array[0][ ]
Array[1][ ]
int Array[4][3] = { {1, 2, 3}, {4, 5, 6},
{7, 8, 9}, {10, 11, 12} } ;
8
13일째 배열과 연결리스트
포인터 배열 (포인터가 저장된 배열)
포인터 배열 사용 예
각 객체는 자유 기억 공간에 저장
그 포인터(자유 기억 공간의 주소)를 포인터
배열에 저장
제한된 스택 메모리의 공간을 절약
9
13일째 배열과 연결리스트
#include <iostream>
using namespace std;
list 13.6
class CAT
{
public:
CAT() { itsAge = 1; itsWeight=5; }
~CAT() {}
int GetAge() const { return itsAge; }
int GetWeight() const { return itsWeight; }
void SetAge(int age) { itsAge = age; }
private:
int itsAge;
int itsWeight;
};
10
13일째 배열과 연결리스트
int main()
{
CAT * Family[500];
int i;
CAT * pCat;
for (i = 0; i < 500; i++)
{
pCat = new CAT;
pCat->SetAge(2*i +1);
Family[i] = pCat;
}
for (i = 0; i < 500; i++)
{
cout << "Cat #" << i+1 << ": ";
cout << Family[i]->GetAge() << endl;
}
return 0;
}
11
13일째 배열과 연결리스트
자유기억공간에 배열 선언
자유기억공간에 배열 선언
CAT * Family = new CAT[ 500 ] ;
배열을 가지고 있는 포인터가 반환
CAT *Family = new CAT [500] ;
CAT *pCat = Family ;
pCat->SetAge(10) ;
// Family[0]
pCat++;
pCat ->SetAge(20) ; // Family[1]
포인터의 연산은 다음 객체를 가리키도록 연산됨
자유 기억 공간의 배열 지우기
delete [ ] Family ;
12
13일째 배열과 연결리스트
포인터와 배열명
Cat FamilyOne[ 500 ] ;
Cat * FamilyTwo[ 500 ] ;
Cat * FamilyThree = new Cat [ 500 ] ;
FamilyOne은 500개의 Cat 배열
배열이름 FamilyOne은 배열의 첫 번째 원소에
대한 상수형 포인터
Family = &FamilyOne[ 0 ]
FamilyTwo 는 500개의 Cat에 대한 포인터를
저장하는 배열 (포인터 배열)
FamilyThree는 자유기억공간상에 500개의 Cat
배열의 처음을 가리키는 포인터
13
13일째 배열과 연결리스트
#include <iostream>
list 13.7
class CAT
{
public:
CAT() { itsAge = 1; itsWeight=5; }
~CAT();
int GetAge() const { return itsAge; }
int GetWeight() const { return itsWeight; }
void SetAge(int age) { itsAge = age; }
private:
int itsAge;
int itsWeight;
};
CAT :: ~CAT()
{
// cout << "Destructor called!\n";
}
14
13일째 배열과 연결리스트
int main()
{
CAT * Family = new CAT[500];
int i;
for (i = 0; i < 500; i++)
{
Family[i].SetAge(2*i +1);
}
for (i = 0; i < 500; i++)
{
std::cout << "Cat #" << i+1 << ": ";
std::cout << Family[i].GetAge() << std::endl;
}
delete [] Family;
return 0;
}
15
13일째 배열과 연결리스트
Char 배열 (문자 배열)
문자열
널(‘\0’) 문자로 끝나는 문자의 배열
널 (‘\0’) 문자 : 문자열의 끝임을 표시
char Greeting [ ] = { ‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘ ‘,
‘W’, ‘o’, ‘r’, ‘l’, ‘d’, ‘\0’ } ;
char Greeting [ ] = “Hello World” ;
초기화되지 않은 문자 배열 생성 가능
cin을 통하여 문자 배열 채우기 가능
공백 문자를 입력의 끝으로 간주하는 문제
cin.get( char *, int , char = ‘\n’ )
채워야 할 버퍼
입력 최대 문자 수
입력 종료 문자
16
13일째 배열과 연결리스트
#include <iostream>
list 13.8
int main()
{
char buffer[80];
std::cout << "Enter the string: ";
std::cin >> buffer;
std::cout << "Here is's the buffer: “
<< buffer << std::endl;
return 0;
}
#include <iostream>
using namespace std;
list 13.9
int main()
{
char buffer[80];
cout << "Enter the string: ";
cin.get(buffer, 79);
cout << "Here's the buffer: " << buffer << endl;
return 0;
}
17
13일째 배열과 연결리스트
문자열 함수
#include <string.h>
strcpy( char * des, const char * src )
문자열 복사
strncpy( char *des, const char * src,
unsigned int num )
num개의 문자열 복사
strlen ()
18
13일째 배열과 연결리스트
#include <iostream>
#include <string.h>
list 13.11
int main()
{
const int MaxLength = 80;
char String1[ ] = "No man is an island";
char String2[MaxLength+1];
strncpy(String2,String1,MaxLength);
std::cout << "String1: " << String1 << std::endl;
std::cout << "String2: " << String2 << std::endl;
return 0;
}
19
13일째 배열과 연결리스트
String class
문자열을 표현하기 위한 class
필요한 만큼의 정확한 메모리를 할당하고 유지
operator [ ] ( USHORT offset )
offset 번째의 문자 값 반환
operator + ( const String & )
두 문자열을 연결
operator += ( const String & )
두 문자열을 연결하여 원래의 문자에 덮어 씀
20
13일째 배열과 연결리스트
#include <iostream>
#include <string.h>
using namespace std;
list 13.12
class String
{
public:
String();
String(const char *const);
String(const String &);
~String();
char & operator[ ] (unsigned short offset);
char operator[ ] (unsigned short offset) const;
String operator+ (const String&);
void operator+= (const String&);
String & operator= (const String &);
unsigned short GetLen()const { return itsLen; }
const char * GetString() const { return itsString; }
private:
String (unsigned short);
char * itsString;
unsigned short itsLen;
};
21
13일째 배열과 연결리스트
String::String()
{
itsString = new char[1];
itsString[0] = '\0';
itsLen=0;
}
String::String(unsigned short len)
{
itsString = new char[len+1];
for (unsigned short i = 0; i<=len; i++)
itsString[i] = '\0';
itsLen=len;
}
String::String(const char * const cString)
{
itsLen = strlen(cString);
itsString = new char[itsLen+1];
for (unsigned short i = 0; i<itsLen; i++)
itsString[i] = cString[i];
itsString[itsLen]='\0';
}
22
13일째 배열과 연결리스트
String::String (const String & rhs)
{
itsLen=rhs.GetLen();
itsString = new char[itsLen+1];
for (unsigned short i = 0; i<itsLen;i++)
itsString[i] = rhs[i];
itsString[itsLen] = '\0';
}
String::~String ()
{
delete [ ] itsString;
itsLen = 0;
}
23
13일째 배열과 연결리스트
String& String::operator=(const String & rhs)
{
if (this == &rhs)
return *this;
delete [ ] itsString;
itsLen=rhs.GetLen();
itsString = new char[itsLen+1];
for (unsigned short i = 0; i<itsLen;i++)
itsString[i] = rhs[i];
itsString[itsLen] = '\0';
return *this;
}
char & String::operator[ ](unsigned short offset)
{
if (offset > itsLen)
return itsString[itsLen-1];
else
return itsString[offset];
}
char String::operator[ ](unsigned short offset) const
{
if (offset > itsLen)
return itsString[itsLen-1];
else
return itsString[offset];
}
24
13일째 배열과 연결리스트
String String::operator+(const String& rhs)
{
unsigned short totalLen = itsLen + rhs.GetLen();
String temp(totalLen);
unsigned short i;
for ( i= 0; i<itsLen; i++)
temp[i] = itsString[i];
for (unsigned short j = 0; j<rhs.GetLen(); j++, i++)
temp[i] = rhs[j];
temp[totalLen]='\0';
return temp;
}
void String::operator+=(const String& rhs)
{
unsigned short rhsLen = rhs.GetLen();
unsigned short totalLen = itsLen + rhsLen;
String temp(totalLen);
unsigned short i;
for (i = 0; i<itsLen; i++)
temp[i] = itsString[i];
for (unsigned short j = 0; j<rhs.GetLen(); j++, i++)
temp[i] = rhs[i-itsLen];
temp[totalLen]='\0';
*this = temp;
}
25
13일째 배열과 연결리스트
int main()
{
String s1("initial test");
cout << "S1:\t" << s1.GetString() << endl;
char * temp = "Hello World";
s1 = temp;
cout << "S1:\t" << s1.GetString() << endl;
char tempTwo[20];
strcpy(tempTwo,"; nice to be here!");
s1 += tempTwo;
cout << "tempTwo:\t" << tempTwo << endl;
cout << "S1:\t" << s1.GetString() << endl;
cout << "S1[4]:\t" << s1[4] << endl;
s1[4]='x';
cout << "S1:\t" << s1.GetString() << endl;
cout << "S1[999]:\t" << s1[999] << endl;
26
13일째 배열과 연결리스트
String s2(" Another string");
String s3;
cout << "My Break\n";
s3 = s1+s2;
cout << "S3:\t" << s3.GetString() << endl;
String s4;
s4 = "Why does this work?";
cout << "S4:\t" << s4.GetString() << endl;
return 0;
}
27
13일째 배열과 연결리스트
연결리스트 (Linked List)
데이터와 포인터의 쌍으로 이루어지는 자료
구조
데이터를 필요한 만큼 쓸 수 있음
삽입과 삭제가 용이
노드
데이터
포인터
포인터는 연결된 다른 노드를 가리킴
첫 번째 노드를 헤더( Header )
마지막 노드를 테일( Tail )
연결 리스트의 종류
단방향 연결 ( Singly linked )
양방향 연결 ( Doubly linked )
트리 ( Tree )
28
13일째 배열과 연결리스트
연결리스트 (Linked List)
단방향 연결 : Singly linked
데이터
데이터
데이터
데이터
포인터
포인터
포인터
포인터
양방향 연결 : Doubly linked
데이터
데이터
데이터
데이터
포인터
포인터
포인터
포인터
포인터
포인터
포인터
포인터
29
13일째 배열과 연결리스트
연결리스트 (Linked List)
트리 (Tree)
데이터
포인터
포인터
데이터
포인터
데이터
포인터
포인터
데이터
포인터
포인터
데이터
포인터
포인터
30
포인터
데이터
포인터
포인터
13일째 배열과 연결리스트
#include <iostream>
using namespace std;
list 13.13
enum { kIsSmaller, kIsLarger, kIsSame};
class Data
{
public:
Data(int val):myValue(val){ }
~Data(){ }
int Compare(const Data &);
void Show() { cout << myValue << endl; }
private:
int myValue;
};
int Data::Compare(const Data & theOtherData)
{
if (myValue < theOtherData.myValue)
return kIsSmaller;
if (myValue > theOtherData.myValue)
return kIsLarger;
else
return kIsSame;
}
31
13일째 배열과 연결리스트
class Node
{
public:
Node(){ }
virtual ~Node(){ }
virtual Node * Insert(Data * theData)=0;
virtual void Show( ) = 0;
private:
};
class InternalNode: public Node
{
public:
InternalNode(Data * theData, Node * next);
~InternalNode() { delete myNext; delete myData; }
virtual Node * Insert(Data * theData);
virtual void Show( )
{
myData->Show(); myNext->Show();
}
private:
Data * myData;
Node * myNext;
};
32
13일째 배열과 연결리스트
InternalNode::InternalNode(Data * theData, Node * next):
myData(theData),myNext(next)
{
}
Node * InternalNode::Insert(Data * theData)
{
int result = myData->Compare(*theData);
switch(result)
{
case kIsSame:
case kIsLarger:
InternalNode * dataNode
= new InternalNode(theData, this);
return dataNode;
case kIsSmaller:
myNext = myNext->Insert(theData);
return this;
}
return this;
}
33
13일째 배열과 연결리스트
class TailNode : public Node
{
public:
TailNode(){ }
~TailNode(){ }
virtual Node * Insert(Data * theData);
virtual void Show() { }
private:
};
Node * TailNode::Insert(Data * theData)
{
InternalNode * dataNode
= new InternalNode(theData, this);
return dataNode;
}
34
13일째 배열과 연결리스트
class HeadNode : public Node
{
public:
HeadNode();
~HeadNode() { delete myNext; }
virtual Node * Insert(Data * theData);
virtual void Show() { myNext->Show(); }
private:
Node * myNext;
};
HeadNode::HeadNode()
{
myNext = new TailNode;
}
Node * HeadNode::Insert(Data * theData)
{
myNext = myNext->Insert(theData);
return this;
}
35
13일째 배열과 연결리스트
class LinkedList
{
public:
LinkedList();
~LinkedList() { delete myHead; }
void Insert(Data * theData);
void ShowAll() { myHead->Show(); }
private:
HeadNode * myHead;
};
LinkedList::LinkedList()
{
myHead = new HeadNode;
}
void LinkedList::Insert(Data * pData)
{
myHead->Insert(pData);
}
36
13일째 배열과 연결리스트
int main()
{
Data * pData;
int val;
LinkedList ll;
for (;;)
{
cout << "What value? (0 to stop): ";
cin >> val;
if (!val)
break;
pData = new Data(val);
ll.Insert(pData);
}
ll.ShowAll();
return 0;
}
37