알고리즘 공부의 기반이 된다.
컴퓨터 안의 데이터를 어떻게 저장 시킬 것인지 논하는 과목. -> 최적화의 방법을 생각 할 수 있음
C#의 List는 어떤식으로 내부에 저장될까? 배열이랑 같은 방식으로 저장된다.
List< T > list = new List(10); => 크기를 먼저 잡아주는 것이 좋다. 만약 10 크기로 잡았는데 100이 필요하다면 전체 리스트를 복사해서 옮겨진다. 따라서, 애초부터 크기를 생각하고 잡는 것이 좋다.
과거의 조상님들이 프로그래밍을 어떤 생각을 통해 발전시켰는지 알 수 있음.
다른 프로그래머들과 의사소통을 할 수 있고, 알아보기 쉬운 . 즉, 가독성 있는 프로그램을 짤 수 있는 기반이 된다.
문제를 어떻게 해결하는가에 대한 경험을 해볼 수 있다.
전공 하지 않으신 분들은 전공 지식을 공부 할 수 있는 기반을 마련할 수 있다.











namespace LionStudy_00
{
public class LinkedListNode<T> //방 1개를 만든 것. Data와 다음 노드로 갈 Next가 필요함.
{ //LinkedListNode는 헤드 노드(첫 노드)만 알고 있다.
public T Data;
public LinkedListNode<T> Next;
public LinkedListNode(T data)
{
Data = data;
Next = null;
}
}
public class LinkedList<T>
{
private LinkedListNode<T> head; //헤드 노드를 선언
public LinkedList()
{
head = null; //현재 헤드 노드는 아무것도 들어있지 않으므로 생성자에서 null로 초기화
}
public void Add(T data)
{
LinkedListNode<T> node = new LinkedListNode<T>(data);
if(head == null)
{
head = node; //데이터 추가 한 것이 첫 노드
}
else
{
LinkedListNode<T> current = head;
while(current.Next != null) //현재 노드 기준으로 다음 노드가 있을 경우
{
current = current.Next;
}
current.Next = node; //다음 노드가 없을 경우 마지막 노드를 의미한다. 마지막 노드에
//마지막 데이터가 들어온다.
}
}
public void Print()
{
if(head == null)
{
Console.WriteLine("리스트가 비어있음");
return;
}
LinkedListNode<T> current = head;
while(current != null)
{
Console.Write(current.Data + "=>");
current = current.Next;
}
Console.WriteLine("null");
}
}
}
class Program
{
static void Main(string[] args)
{
LionStudy_00.LinkedList<string> list = new LionStudy_00.LinkedList<string>();
list.Add("어허");
list.Add("이건");
list.Add("뭔가요?");
list.Print(); //어허 => 이건 => 뭔가요? => null
}
}


LinkedListNode<T> node = new LinkedListNode<T>(data); //이 과정을 통해 방 하나가 생성되었다.
if(head == null)
{
head = node; //데이터 추가 한 것이 첫 노드
}

else
{
LinkedListNode<T> current = head;
//..생략
}
else
{
LinkedListNode<T> current = head;
while(current.Next != null) //현재 노드 기준으로 다음 노드가 있을 경우
{
current = current.Next;
}
}
else
{
LinkedListNode<T> current = head;
while(current.Next != null) //현재 노드 기준으로 다음 노드가 있을 경우
{
current = current.Next;
}
current.Next = node; //다음 노드가 없을 경우 마지막 노드를 의미한다. 마지막 노드에
//마지막 데이터가 들어온다.
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LionStudy_00
{
public class LinkedListNode<T> //방 1개를 만든 것. Data와 다음 노드로 갈 Next가 필요함.
{ //LinkedListNode는 헤드 노드(첫 노드)만 알고 있다.
public T Data;
public LinkedListNode<T> Next;
public LinkedListNode(T data)
{
Data = data;
Next = null;
}
}
public class LinkedList<T>
{
private LinkedListNode<T> head; //헤드 노드를 선언
public LinkedList()
{
head = null; //현재 헤드 노드는 아무것도 들어있지 않으므로 생성자에서 null로 초기화
}
public void Add(T data)
{
//..생략
}
public void Remove(T data)
{
if (head == null)
{
Console.WriteLine("Blanked"); // 비었다고 출력
return;
}
if (head.Data.Equals(data)) // 헤더의 데이터가 입력한 데이터와 같다면
{
head = head.Next; // 다음 데이터를 헤더로 설정
return;
}
LinkedListNode<T> current = head; // 현재 노드 : 시작 노드
LinkedListNode<T> previous = null; // 이전 노드
while (current != null && !current.Data.Equals(data)) // 현재 노드가 비지 않았고
{// 입력한 데이터와 같지 않다면 반복
previous = current; // 이전 노드를 현재 노드로 지정
current = current.Next; // 현재 노드를 다음 노드로 지정
}
if (current == null) // 끝까지 탐색해도 없을 때
{
Console.WriteLine("Not Found Data"); // 데이터를 찾지 못함
}
else
{
previous.Next = current.Next; // 이전 노드의 행선지를 다음 노드의 행선지로 지정
}
}
public void Print()
{
if(head == null)
{
Console.WriteLine("리스트가 비어있음");
return;
}
LinkedListNode<T> current = head;
while(current != null)
{
Console.Write(current.Data + "=>");
current = current.Next;
}
Console.WriteLine("null");
}
}
//데이터 추가, 삭제 , 찾기
}
class Program
{
static void Main(string[] args)
{
LionStudy_00.LinkedList<string> list = new LionStudy_00.LinkedList<string>();
list.Add("어허");
list.Add("이건");
list.Add("뭔가요?");
list.Remove("이건");
list.Print(); //어허 -> 뭔가요 -> null
}
}
어허 -> 이건 -> 뭔가요 부분에서 이건을 Remove하게 되면 어허 -> 뭔가요가 된다. 즉, 중간에 있는 노드를 삭제하면 첫번째 노드가 세번째 노드를 가리킨다.
만약, 첫번째 노드를 삭제하면 두번째 노드가 세번재 노드를 가리킨다.

따라서, 코드를 작성하면
if (head.Data.Equals(data)) // 헤더의 데이터가 입력한 데이터와 같다면
{
head = head.Next; // 다음 데이터를 헤더로 설정
return;
}

LinkedListNode<T> current = head; // 현재 노드 : 시작 노드
LinkedListNode<T> previous = null; // 이전 노드
while (current != null && !current.Data.Equals(data)) // 현재 노드가 비지 않았고
{// 입력한 데이터와 같지 않다면 반복
previous = current; // 이전 노드를 현재 노드로 지정
current = current.Next; // 현재 노드를 다음 노드로 지정
}
else
{
previous.Next = current.Next; // 이전 노드의 행선지를 다음 노드의 행선지로 지정
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LionStudy_00
{
public class LinkedListNode<T> //방 1개를 만든 것. Data와 다음 노드로 갈 Next가 필요함.
{ //LinkedListNode는 헤드 노드(첫 노드)만 알고 있다.
public T Data;
public LinkedListNode<T> Next;
public LinkedListNode(T data)
{
Data = data;
Next = null;
}
}
public class LinkedList<T>
{
private LinkedListNode<T> head; //헤드 노드를 선언
public LinkedList()
{
head = null; //현재 헤드 노드는 아무것도 들어있지 않으므로 생성자에서 null로 초기화
}
public void Add(T data)
{
LinkedListNode<T> node = new LinkedListNode<T>(data);
if(head == null)
{
head = node; //데이터 추가 한 것이 첫 노드
}
else
{
LinkedListNode<T> current = head;
while(current.Next != null) //현재 노드 기준으로 다음 노드가 있을 경우
{
current = current.Next;
}
current.Next = node; //다음 노드가 없을 경우 마지막 노드를 의미한다. 마지막 노드에
//마지막 데이터가 들어온다.
}
}
//...생략
public T PopFirst()
{
if (head == null)
{
return default;
}
T data = head.Data; // 첫 데이터를 가져옴
head = head.Next; // 헤더를 다음 데이터로 지정
return data;
}
//...생략
}
class Program
{
static void Main(string[] args)
{
LionStudy_00.LinkedList<string> list = new LionStudy_00.LinkedList<string>();
list.Add("어허");
list.Add("이건");
list.Add("뭔가요?");
list.Remove("이건"); ///어허 -> 뭔가요 -> null
list.PopFirst(); //뭔가요 -> null
list.Print(); // 뭔가요 -> null
}
}

T data = head.Data; // 첫 데이터를 가져옴
head = head.Next; // 헤더를 다음 데이터로 지정

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LionStudy_00
{
public class LinkedListNode<T> //방 1개를 만든 것. Data와 다음 노드로 갈 Next가 필요함.
{ //LinkedListNode는 헤드 노드(첫 노드)만 알고 있다.
public T Data;
public LinkedListNode<T> Next;
public LinkedListNode(T data)
{
Data = data;
Next = null;
}
}
public class LinkedList<T>
{
private LinkedListNode<T> head; //헤드 노드를 선언
public LinkedList()
{
head = null; //현재 헤드 노드는 아무것도 들어있지 않으므로 생성자에서 null로 초기화
}
public void Add(T data)
{
//..생략
}
public void Remove(T data)
{
//..생략
}
public T PopFirst()
{
//..생략
}
public T PopLast()
{
if (head == null)
{
return default;
}
if (head.Next == null) // 헤더 노드가 끝일 때
{
T data2 = head.Data; // 헤더 노드의 데이터 반납
head = null; // 헤더 노드를 비움
return data2;
}
LinkedListNode<T> current = head; // 현재 노드 : 헤더
LinkedListNode<T> previous = null; // 이전 노드
while (current.Next != null) // 현재 노드의 목적지가 빌 때까지 반복
{
previous = current; // 이전 노드를 현재 노드로 지정
current = current.Next; // 현재 노드를 다음 노드로 지정
}
T data = current.Data; // 마지막 노드의 데이터를 반납
previous.Next = null; // 이전 노드의 목적지를 비움 / 위에서 가장 끝의 노드를 반납했기 때문이다
return data;
}
public void Print()
{
//..생략
}
}
//데이터 추가, 삭제 , 찾기
}
class Program
{
static void Main(string[] args)
{
LionStudy_00.LinkedList<string> list = new LionStudy_00.LinkedList<string>();
list.Add("어허");
list.Add("이건");
list.Add("뭔가요?");
list.Remove("이건"); ///어허 -> 뭔가요 -> null
list.PopLast(); //어허 -> null
list.Print(); // 어허 -> null
}
}

LinkedListNode<T> current = head; // 현재 노드 : 헤더
LinkedListNode<T> previous = null; // 이전 노드
while (current.Next != null) // 현재 노드의 목적지가 빌 때까지 반복
{
previous = current; // 이전 노드를 현재 노드로 지정
current = current.Next; // 현재 노드를 다음 노드로 지정
}
T data = current.Data; // 마지막 노드의 데이터를 반납
previous.Next = null; // 이전 노드의 목적지를 비움 / 위에서 가장 끝의 노드를 반납했기 때문이다
return data;
public class LinkedListNode<T>
{
public T Data;
public LinkedListNode<T> Next;
public LinkedListNode(T data)
{
Data = data;
Next = null;
}
}
public class LinkedList<T>
{
private LinkedListNode<T> head; //참조 변수 선언
public LinkedList() //생성자 실행 시,
{
head = null; //⭐ 처음 노드. 즉, 헤드 노드는 아무런 값이 들어있지 않으므로 null 처리 한다. ⭐
}
}
public class LinkedList<T>
{
private LinkedListNode<T> head; //헤드 노드를 선언
public LinkedList()
{
head = null; //현재 헤드 노드는 아무것도 들어있지 않으므로 생성자에서 null로 초기화
}
public void Add(T data) //다른 클래스에서 Add(5); 할 경우, data = 5
{
LinkedListNode<T> node = new LinkedListNode<T>(data);
if(head == null)
{
head = node; //데이터 추가 한 것이 첫 노드
}
else
{
LinkedListNode<T> current = head;
while(current.Next != null) //현재 노드 기준으로 다음 노드가 있을 경우
{
current = current.Next;
}
current.Next = node; //다음 노드가 없을 경우 마지막 노드를 의미한다. 마지막 노드에
//마지막 데이터가 들어온다.
}
}
}
LinkedListNode<T> node = new LinkedListNode<T>(data);


if(head == null)
{
head = node; //데이터 추가 한 것이 첫 노드
}

using LionStudy_00;
class Program
{
static void Main(string[] args)
{
LionStudy_00.LinkedList<string> list = new LionStudy_00.LinkedList<string>();
//LinkedList 생성자 호출 -> head = null
}
}




using LionStudy_00;
class Program
{
static void Main(string[] args)
{
LionStudy_00.LinkedList<string> list = new LionStudy_00.LinkedList<string>();
list.Add("5");
}
}



class Program
{
static void Main(string[] args)
{
LionStudy_00.LinkedList<string> list = new LionStudy_00.LinkedList<string>();
list.Add("5");
list.Add("6");
}
}









class Program
{
static void Main(string[] args)
{
LionStudy_00.LinkedList<string> list = new LionStudy_00.LinkedList<string>();
list.Add("5");
list.Add("6");
list.Remove("5"); //5 삭제
}
}

아래는 현재 상태이다. 처음에 5 데이터 삽입 -> 6 데이터 삽입을 하였다.












if문은 실행 하지 않고, else문이 실행된다.





using LionStudy_00;
class Program
{
static void Main(string[] args)
{
LionStudy_00.LinkedList<string> list = new LionStudy_00.LinkedList<string>();
list.Add("5");
list.Add("6");
list.PopFirst();
}
}






using LionStudy_00;
class Program
{
static void Main(string[] args)
{
LionStudy_00.LinkedList<string> list = new LionStudy_00.LinkedList<string>();
list.Add("5");
list.Add("6");
list.PopLast();
}
}















using LionStudy_00;
class Program
{
static void Main(string[] args)
{
LionStudy_00.LinkedList<string> list = new LionStudy_00.LinkedList<string>();
list.Add("5");
list.Add("6");
list.PopLast(); //6이 뽑힘
list.PopLast(); //5가 뽑힘
}
}















nextNode.Next = head; // 새로 추가 된 노드의 Next가 head를 가리킨다. (가리키기 위해 nexNode.Next가 head의 주소를 알고 있어야 한다.)

head.Prev = nextNode; // head 노드의 Prev가 nextNode를 가리켜야 한다. (가리키기 위해 head가 nextNode의 주소를 알고 있어야 한다.)

head = nextNode; //head 노드가 nextNode를 가리켜야 한다. (가리키기 위해 head가 nextNode의 주소를 알고 있어야 한다)




head = newNode;
tail = newNode;





else
{
tail.Next = newNode; // tail의 Next 노드가 newNode를 가리킨다.(가리키기 위해 nextNode의 주소를 tail의 Next에게 넘겨야 한다.
newNode.Prev = tail; // newNode의 Prev 노드가 tail을 가리킨다. (가리키기 위해 tail의 주소를 newNode의 Prev에게 넘겨야 한다.
}

tail = newNode; //tail이 newNode를 가리켜야 한다.(가리키기 위해 newNode의 주소를 tail에게 넘겨야 한다.)



















using LionStudy_00;
class Program
{
static void Main(string[] args)
{
Tree<string> tree = new Tree<string>("Root");
TreeNode<string> child1 = tree.Root.AddChild(new TreeNode<string>("Child1"));
TreeNode<string> child2 = tree.Root.AddChild(new TreeNode<string>("Child2"));
child1.AddChild(new TreeNode<string>("grandChild1"));
child2.AddChild(new TreeNode<string>("grandChild2"));
child2.AddChild(new TreeNode<string>("grandChild3"));
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LionStudy_00
{
public class TreeNode<T>
{
//트리는 Data와 자식이 들어있다.
public T Data; //
public List<TreeNode<T>> Children; //자식
public TreeNode(T data)
{
Data = data;
Children = new List<TreeNode<T>>();
}
public TreeNode<T> AddChild(TreeNode<T> child)
{
Children.Add(child);
return child;
}
}
public class Tree<T>
{
public TreeNode<T> Root; //트리는 무조건 Root가 있어야함
public Tree(T rootData)
{
Root = new TreeNode<T>(rootData); //매개변수 rootData를 Root에 저장
}
}
}





