착한천사 김경록입니다.
제가 알기로는 linked list에는 많은 종료가 있다는걸로 아는데요..
N-Linked list
쉽게 말해서, 단방향, 양방향, N방향 으로 나눠졌떤거 같던데..
즉, 단방향의 예는 워낙 안좋다보니 별로 없네용(사실 제가 거의 안써봐서리.) 흐흐흐..
양방향은 B-Tree,
N방향은 B*-Tree 구현에 썼던걸로 기억이 가물가물하게 나는군요
일반, 단방향 linked llist는 아주, 무쟈게 쉬울겁니다..
"이론 = 실기"의 대표적 사례라고 할 수 있겠죠..
물론, linked list의 기본 이론은 아실꺼라 생각하고
그적그적 적어가보도로 하죠..
단방향 linked list의 최대 단점은, liked list의
중간에 있는 놈을 제거해 버리면, linked list는 아작나 버린다는
그런 엄청난 단점을 가진 linked list입니다.
N방향 linked 리스트는
선행 레코드의 포인트와 다음 레코드의 포인트, 그리고 값을 가지는
3가지 유형을 가진 record 혹은 class들의 연결이라고 보시면 됩니다.
서론이 길었네요..
아래 예제는 record로 구현한 단방향 linked list의 예제입니다..
(사실, linked list에서는 record나 class나 뭐.. 거기서 거기.. 큽큽)
Type
RLinkedList = Record
r_Value: ShortString;
r_NextRecord: Pointer;
End;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Panel1: TPanel;
Label1: TLabel;
Button2: TButton;
Label2: TLabel;
Edit1: TEdit;
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
prp_LinkedRoot: Pointer; // Linked List의 Root (첫시작점)
prp_CurrentNode: Pointer;
protected
Procedure AddLink(as_Value: ShortString); //Link를 추가합니다..
Procedure ReadLink; //추가한 Link list를 쭈~~욱 읽어 봐야죠?
//추가한 순서대로 되었는지 확인도 해야되고..
Public
//생성자를 재선언할 필요는 없지만,
//Class를 안쓸수도 있기 때문에 일부러 선언,
//기냥, Project를 시작하니까, 덜렁 Form이 하나 나타나서리..
//귀차니즘으로 인하여.. Form을 안바꾸고.. 그냥 Coding함.. 큽큽..
//귀차니즘을 이해하시길..
Constructor Create(Owner: TComponent); override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
Procedure TForm1.AddLink(as_Value:ShortString);
Var
l_LinkedList: ^RLinkedList; //꼭 ^RLinkedList를 안쓰고, Pointer를 사용해도 상관없음
begin //왜 그런지 Memory Address 차원에서 생각해 보셈.. 너무 쉽나??
Try
GetMem(l_LinkedList, SizeOf(RLinkedList));
Except
On EOutOfMemory Do
Begin
MessageBox(Self.Handle, 'Memory가 부족합니다..', '에러', MB_ICONERROR);
Exit;
End;
End;
With RLinkedList(l_LinkedList^) Do
Begin
r_Value := as_Value;
Memo1.Lines.Add(as_Value); //추가한거 보기.. 큽큽.. 나중에 추가한 순서대로 있나 확인용
r_NextRecord := Nil;
End;
//Root가 NULL이면, Root에 현재 생성한 Link를 할당한다.
//그렇지 않으면, 현재 할당받은 Recorder의 Pointer를
//현재 위치 Pointer(prp_CurrentNode)에 할당하여,
//마지막 Node의 위치를 이동한다.
If prp_LinkedRoot = Nil Then
Begin
prp_LinkedRoot := l_LinkedList; //첫번째 추가는 Root에 할당
prp_CurrentNode:= l_LinkedList; //첫번째 추가일때는 마지막 Node는 항당 Root
End
Else Begin
RLinkedList(prp_CurrentNode^).r_NextRecord := l_LinkedList; //최초
prp_CurrentNode := l_LinkedList; //추가된곳에 현재 Node 이동
End;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
//Linked List의 효용이 끝났을 시에는 Memory를 해제시켜야함..
//Getmem으로 할당받은 Memory는 FreeMem으로 해제시켜야 하는데.. 못하겠네.. 큰일이당..
//왜냐하면, 단일 Linked list의 최대 단점인 list의 중간에서
//Link를 끊어 버리면, 그 이후부터의 Linked List에 대한
//Memory 해제를 할 수 없다는 최대의 단점 발생..
// 간단히 말해서, 연결이 끊어진 놈들의 Memory 해제는 불가능하다는 뜻..
// 내 PC 맛가는거 아닌가.. 모르겠네.. 큽큽
prp_LinkedRoot := Nil;
prp_CurrentNode := Nil;
end;
Constructor TForm1.Create(Owner: TComponent);
begin
inherited Create(Owner); //상속처리
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Lines.Clear;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ReadLink;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
If Trim(Edit1.Text) = '' Then
Begin
MessageBox(Self.Handle, '추가할 문자는 넣으셔야죵~~', '경고', MB_ICONERROR);
Exit;
End;
제가 알기로는 linked list에는 많은 종료가 있다는걸로 아는데요..
N-Linked list
쉽게 말해서, 단방향, 양방향, N방향 으로 나눠졌떤거 같던데..
즉, 단방향의 예는 워낙 안좋다보니 별로 없네용(사실 제가 거의 안써봐서리.) 흐흐흐..
양방향은 B-Tree,
N방향은 B*-Tree 구현에 썼던걸로 기억이 가물가물하게 나는군요
그러니까, 제가 옛날.. 아주 옛날.. 그러니까.. 96년도에..
C++로 구현한적이 있었는데..
무쟈게 쉬웠던걸로 기억이 나는군요..
Tree구조에서 Full-Tree구조를 만드는게 굉장히 귀찮았던걸로
기억이 나는데..
일반, 단방향 linked llist는 아주, 무쟈게 쉬울겁니다..
"이론 = 실기"의 대표적 사례라고 할 수 있겠죠..
물론, linked list의 기본 이론은 아실꺼라 생각하고
그적그적 적어가보도로 하죠..
단방향 linked list의 최대 단점은, liked list의
중간에 있는 놈을 제거해 버리면, linked list는 아작나 버린다는
그런 엄청난 단점을 가진 linked list입니다.
N방향 linked 리스트는
선행 레코드의 포인트와 다음 레코드의 포인트, 그리고 값을 가지는
3가지 유형을 가진 record 혹은 class들의 연결이라고 보시면 됩니다.
서론이 길었네요..
아래 예제는 record로 구현한 단방향 linked list의 예제입니다..
(사실, linked list에서는 record나 class나 뭐.. 거기서 거기.. 큽큽)
<!--CodeS-->
unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Controls, FORMS, StdCtrls,
ExtCtrls;
Type
RLinkedList = Record
r_Value: ShortString;
r_NextRecord: Pointer;
End;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Panel1: TPanel;
Label1: TLabel;
Button2: TButton;
Label2: TLabel;
Edit1: TEdit;
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
prp_LinkedRoot: Pointer; // Linked List의 Root (첫시작점)
prp_CurrentNode: Pointer;
protected
Procedure AddLink(as_Value: ShortString); //Link를 추가합니다..
Procedure ReadLink; //추가한 Link list를 쭈~~욱 읽어 봐야죠?
//추가한 순서대로 되었는지 확인도 해야되고..
Public
//생성자를 재선언할 필요는 없지만,
//Class를 안쓸수도 있기 때문에 일부러 선언,
//기냥, Project를 시작하니까, 덜렁 Form이 하나 나타나서리..
//귀차니즘으로 인하여.. Form을 안바꾸고.. 그냥 Coding함.. 큽큽..
//귀차니즘을 이해하시길..
Constructor Create(Owner: TComponent); override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
Procedure TForm1.AddLink(as_Value:ShortString);
Var
l_LinkedList: ^RLinkedList; //꼭 ^RLinkedList를 안쓰고, Pointer를 사용해도 상관없음
begin //왜 그런지 Memory Address 차원에서 생각해 보셈.. 너무 쉽나??
Try
GetMem(l_LinkedList, SizeOf(RLinkedList));
Except
On EOutOfMemory Do
Begin
MessageBox(Self.Handle, 'Memory가 부족합니다..', '에러', MB_ICONERROR);
Exit;
End;
End;
With RLinkedList(l_LinkedList^) Do
Begin
r_Value := as_Value;
Memo1.Lines.Add(as_Value); //추가한거 보기.. 큽큽.. 나중에 추가한 순서대로 있나 확인용
r_NextRecord := Nil;
End;
//Root가 NULL이면, Root에 현재 생성한 Link를 할당한다.
//그렇지 않으면, 현재 할당받은 Recorder의 Pointer를
//현재 위치 Pointer(prp_CurrentNode)에 할당하여,
//마지막 Node의 위치를 이동한다.
If prp_LinkedRoot = Nil Then
Begin
prp_LinkedRoot := l_LinkedList; //첫번째 추가는 Root에 할당
prp_CurrentNode:= l_LinkedList; //첫번째 추가일때는 마지막 Node는 항당 Root
End
Else Begin
RLinkedList(prp_CurrentNode^).r_NextRecord := l_LinkedList; //최초
prp_CurrentNode := l_LinkedList; //추가된곳에 현재 Node 이동
End;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
//Linked List의 효용이 끝났을 시에는 Memory를 해제시켜야함..
//Getmem으로 할당받은 Memory는 FreeMem으로 해제시켜야 하는데.. 못하겠네.. 큰일이당..
//왜냐하면, 단일 Linked list의 최대 단점인 list의 중간에서
//Link를 끊어 버리면, 그 이후부터의 Linked List에 대한
//Memory 해제를 할 수 없다는 최대의 단점 발생..
// 간단히 말해서, 연결이 끊어진 놈들의 Memory 해제는 불가능하다는 뜻..
// 내 PC 맛가는거 아닌가.. 모르겠네.. 큽큽
prp_LinkedRoot := Nil;
prp_CurrentNode := Nil;
end;
Constructor TForm1.Create(Owner: TComponent);
begin
inherited Create(Owner); //상속처리
prp_LinkedRoot := Nil; //Linked List의 Root
prp_CurrentNode := Nil; //Linked List Terminal Node(최고말단)는 없음
end;
procedure TForm1.ReadLink;
Var
l_CurNode: Pointer; //제가 l_CurNode의 Type을 ^RLinkedList로 선언안했는지
//헷갈리시죠? 연구해 보세요.. 이건 문제에요.. 이것도 너무쉽나요?
//문제를 만들려고, Pointer와 ^RLinkedList를 섞어보긴 했습니다만..
//너무 쉬운가요?? 큽큽
begin
l_CurNode := prp_LinkedRoot;
While l_CurNode <> Nil Do
Begin
MessageBox(Self.Handle, PChar('값 : ' + RLinkedList(l_CurNode^).r_Value), '알림',
MB_ICONWARNING);
l_CurNode := RLinkedList( l_CurNode^ ).r_NextRecord;
End;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Lines.Clear;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ReadLink;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
If Trim(Edit1.Text) = '' Then
Begin
MessageBox(Self.Handle, '추가할 문자는 넣으셔야죵~~', '경고', MB_ICONERROR);
Exit;
End;
AddLink(Edit1.Text);
end;
end.
<!--CodeE-->