자료 구조란
- 사전적 의미 : 데이터를 처리하는 입장에서 데이터 사이에 존재하는 관계를 개념적으로 잡은 것
- 데이터를 효율적으로 사용할 수 있도록 구조를 만들어서 저장하는 것
어떻게 효율적으로 저장할 것이냐 ?
선형 구조
- 데이터를 선의 형태로 일렬로 저장.
- 스택, 큐, 연결리스트
비 선형 구조
- 데이터를 선의 형태가 아닌 다른 형태로 저장하는 방식
- 이전 데이터와 이후 데이터는 1대 다 관계를 가짐
- 트리(보통 위에서 밑으로. 뿌리구조), 그래프
* 스택(Stack) (일종의 약속. 이렇게 사용하자)
- 삽입/삭제가 한쪽 끝에서만 수행되는 구조
- LIFO 구조
입력 : Push / 출력 : Pop
바텀 / 탑을 이용해서 스택의 영역을 나타낸다.
푸쉬 : 탑의 위치가 올라감 / 팝 : 탑의 위치를 내려줌
*큐(Queue)
- 한쪽에서는 삽입만 한쪽에서 삭제만 수행되는 구조
- FIFO : 먼저 들어간 데이터가 먼저 나오는 구조
- Front와 Rear를 통해 사용되며, 데이터 삽입시 rear가 이동한다. 데이터 출력시 front가 움직인다.
*리스트
- 데이터를 순서대로 저장해 놓는 구조
- 대표적으로 배열.
- 스택/큐도 넓은 의미로 리스트에 포함
연결리스트 (뒤에 있는 데이터의 위치정보가 필요하므로 포인터사용)
- 데이터들을 링크를 통해 연결시켜 저장하는 구조
- (데이터 / 링크) 링크는 다음 데이터의 주소를 가지고 있어야 한다.
따라서 구조체를 사용해서 (데이터형 / 다음 구조체에 대한 포인터변수) = 합쳐서 노드. 데이터와 주소로 구성
ex)
typedef struct person_node{
char name[20];
char blood[10];
int age;
struct person_node *p;
}person_node;
void main()
{
person_node p1;
strcpy(p1.name, "홍길동");
strcpy(p1.blood, "RH+B");
p1.age = 100;
p1.p = NULL;
person_node p2;
strcpy(p2.name, "고길동");
strcpy(p2.blood, "RH+AB");
p2.age=150;
p2.p=NuLL;
p1.p=&p2;
}
함수로 만들어주고, 동적할당도 더해준다. (데이터가 얼마나 들어갈지 모르므로)
데이터 삽입시에도 임시변수를 넣어서 흐름이 끊기지 않게 해준다.
2번을 없애려면. 1번이 가르키는 주소를 3번으로 바로 이어주면 된다. -> 1번노드에 있는 주소값이 사라져서 Free를 못시켜준다. 따라서 임시변수가 필요. 임시변수 -> 2번을 가리키고 1번을 3번을 이어준다. 그리고 2번에 있는 주소로 Free 시켜준다.
이중연결리스트
앞뒤를 자유롭게 찾아볼수있다.
NULL 10 NULL-> 다음 구조체의 head 시작 주소
(head / data / tail) 형태의 구조체를 생성
앞구조체의 시작주소 20 NULL-> 다음 구조체의 head 시작 주소
(head / data / tail)
앞구조체의 시작주소 30 NULL
(head / data / tail)
15를 삽입하려고 한다.
임시변수 선언 -> 10 tail에 있는 20의 head 시작주소를 임시변수에 넣어주고 15의 tail에 다시 넣어준다.
원형연결리스트도 있다.
*트리(tree)
l link / data / r link
데이터 추가시 왼쪽에 저장되는건 l link에 저장 오른쪽은 r link에 저장
*그래프
컴퓨터로 계산한결과를 그림등으로 나타냄
알고리즘 - 어떤 문제를 해결하기 위한 방법
#include <stdio.h>
typedef struct stack{
int stackArea[5];
int top;
}Stack, *PStack;
void Push(Stack *st, int data)
{
if(st->top>=((int)sizeof(st->stackArea)/4)-1)
{
printf("Stack is FULL\n");
return;
}
st->top++;
st->stackArea[st->top] = data;
}
void main()
{
Stack s;
s.top =-1;
Push(&s,10);
Push(&s,20);
for (int i=0;i<=s.top;i++)
printf("%d",s.stackArea[i]);
}
Stack의 Push와 Pop 구조
#include <stdio.h>
typedef struct stack{
int stackArea[5];
int top;
}Stack, *PStack;
void Push(Stack *st, int data)
{
if(st->top>=((int)sizeof(st->stackArea)/4)-1)
{
printf("Stack is FULL\n");
return;
}
st->top++;
st->stackArea[st->top] = data;
}
void Pop(Stack *st)
{
if(st->top<0)
{
printf("Stack is Void\n");
return;
}
st->stackArea[st->top] = 0;
st->top--;
}
void main()
{
Stack s;
s.top =-1;
Push(&s,10);
Push(&s,20);
Push(&s,30);
Push(&s,40);
Push(&s,50);
Push(&s,60);
/*for (int i=0;i<=s.top;i++)
printf("%d\n",s.stackArea[i]);*/
printf("\n");
Pop(&s);
Pop(&s);
Pop(&s);
Pop(&s);
Pop(&s);
Pop(&s);
Pop(&s);
/*for (int j = s.top;j>-1;j--)
printf("%d\n",s.stackArea[j]);*/
}
연결리스트
포인터변수는 자료형에 상관없이 주소값을 저장하는 4바이트 공간 하나만 생긴다.
구조체등의 포인터 변수라면 아마도 시작주소값 + 각 멤버변수의 바이트수를 더한 공간값으로 가는듯 하다.
구조체->변수
연결리스트에선 탑에 있는 자료만 확인 하면 되므로 중간중간의 데이터는 중요하지 않다.
그냥 보기 -> 탑, 보기->탑 등 탑만 확인하면 된다.
#include<stdio.h>
#include<stdlib.h>
#define EMPTY 0;
struct node {
int data;
struct node* link;
};
typedef struct node Stack;
Stack* top = EMPTY;
void Push(Stack* *top,int data)
{
Stack* tmp;
tmp = (Stack*)malloc(sizeof(Stack));
(*tmp).link = *top;
*top = tmp;
(*top)->data=data;
}
void Pop()
{
if(top==0)
{
printf("Stack is Void\n");
return;
}
Stack* tmp;
tmp = top;
top =(*top).link;
free(tmp);
}
void main()
{
Push(&top,10);
printf("%d,%d\n",top->data,top->link);
Push(&top,20);
printf("%d,%d\n",top->data,top->link);
Push(&top,30);
printf("%d,%d\n",top->data,top->link);
Pop();
printf("%d,%d\n",top->data,top->link);
Pop();
printf("%d,%d\n",top->data,top->link);
Pop();
Pop();
Pop();
}
Queue
#include<stdio.h>
#include<stdlib.h>
#define EMPTY 0;
struct node {
int data;
struct node* link;
};
typedef struct node Stack;
Stack* Front = EMPTY;
Stack* Rear = EMPTY;
void Enqueue(int data)
{
Stack* tmp;
tmp = (Stack*)malloc(sizeof(Stack));
if(Front==0 && Rear==0)
{
Front = tmp;
Rear = tmp;
tmp->data = data;
tmp->link = EMPTY;
}
else
{
Rear->link = tmp;
Rear = tmp;
tmp->data = data;
tmp->link = EMPTY;
}
}
void Dequeue()
{
Stack* tmp;
if(Front!=Rear)
{
tmp = Front->link;
free(Front);
Front = tmp;
}
else if(Front==Rear)
{
tmp = Front;
Front = EMPTY;
Rear = EMPTY;
free(tmp);
printf("Stack is Void\n");
}
}
void main()
{
Enqueue(10);
printf("%d,%d\n",Front->data,Front->link);
printf("%d,%p\n",Rear->data,Rear->link);
Enqueue(20);
printf("%d,%p\n",Front->data,Front->link);
printf("%d,%p\n",Rear->data,Rear->link);
Enqueue(30);
printf("%d,%p\n",Front->data,Front->link);
printf("%d,%p\n",Rear->data,Rear->link);
Dequeue();
printf("%d,%p\n",Front->data,Front->link);
printf("%d,%p\n",Rear->data,Rear->link);
Dequeue();
printf("%d,%p\n",Front->data,Front->link);
printf("%d,%p\n",Rear->data,Rear->link);
Dequeue();
Dequeue();
}
'[ IT ] > C++, 자료구조' 카테고리의 다른 글
자료구조 수업 3 재귀함수 / 연결리스트 - InsertNode,AddNode,DelNode (0) | 2015.06.24 |
---|---|
자료구조 수업 1 (0) | 2015.06.24 |
C++ namespace / using / bool (0) | 2015.06.24 |
C++ 가상함수 / 추상 Class / Template (0) | 2015.06.24 |
C++ String / 상속 / 바인딩 (0) | 2015.06.24 |