Created
May 13, 2019 23:08
-
-
Save Youngchangoon/213435e5feb49acba0e5616b8bcb09d5 to your computer and use it in GitHub Desktop.
Double linked list
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace ConsoleApp1 | |
{ | |
public class Program | |
{ | |
private static DoubleLinkedList<int> doubleLinkedList; | |
static void Main(string[] args) | |
{ | |
doubleLinkedList = new DoubleLinkedList<int>(); | |
// Insert | |
doubleLinkedList.InsertNode(10); | |
doubleLinkedList.InsertNode(20); | |
doubleLinkedList.InsertNode(5, true); | |
doubleLinkedList.InsertNode(15, 2); | |
doubleLinkedList.InsertNode(30); | |
doubleLinkedList.InsertNode(30); | |
doubleLinkedList.InsertNode(30); | |
//// Add Fail Case | |
doubleLinkedList.InsertNode(100, 9); | |
//// Remove | |
doubleLinkedList.RemoveNode(20); | |
doubleLinkedList.RemoveNode(30, true); | |
doubleLinkedList.RemoveAt(1); | |
// Remove Fail Case | |
doubleLinkedList.RemoveAt(100); | |
doubleLinkedList.PrintNode(); | |
} | |
} | |
public class DoubleLinkedList<T> | |
{ | |
public class Node<T> | |
{ | |
public Node() { } | |
public Node(T newData) | |
{ | |
data = newData; | |
} | |
public T data; | |
public Node<T> prev; | |
public Node<T> next; | |
} | |
private Node<T> head; | |
private Node<T> tail; | |
private int totalCount; | |
public DoubleLinkedList() | |
{ | |
// 먼저 머리와 꼬리 노드를 만들어준다. ㅁ(head) -> ㅁ(tail) | |
head = new Node<T>(); | |
tail = new Node<T>(); | |
// (head) -> (tail) -> NULL | |
head.next = tail; | |
head.prev = null; | |
tail.next = null; | |
tail.prev = head; | |
totalCount = 0; | |
} | |
/// <summary> | |
/// 맨 앞이나 맨 뒤에 Data를 삽입한다. | |
/// </summary> | |
/// <param name="newData"> 새로 넣을 데이터 </param> | |
/// <param name="addToHead"> 꼬리에 추가할 것인지 </param> | |
public int InsertNode(T newData, bool addToHead = false) | |
{ | |
var count = 0; | |
var addNode = new Node<T>(newData); | |
var tempNode = addToHead ? head : tail; | |
if (addToHead) | |
{ | |
// 앞으로 넣을 때 | |
var nextNode = tempNode.next; | |
nextNode.prev = addNode; | |
addNode.prev = tempNode; | |
addNode.next = tempNode.next; | |
tempNode.next = addNode; | |
} | |
else | |
{ | |
// 뒤로 넣을 때 | |
var prevNode = tempNode.prev; | |
prevNode.next = addNode; | |
addNode.prev = prevNode; | |
addNode.next = tempNode; | |
tempNode.prev = addNode; | |
} | |
++totalCount; | |
return count; | |
} | |
/// <summary> | |
/// 원하는 index에 Data를 추가한다. | |
/// </summary> | |
/// <param name="newData"></param> | |
/// <param name="index"></param> | |
/// <returns></returns> | |
public int InsertNode(T newData, int index) | |
{ | |
if (index >= totalCount) | |
{ | |
Console.WriteLine("Add Fail..(index: " + index + ")"); | |
return 0; | |
} | |
var count = 0; | |
var addNode = new Node<T>(newData); | |
var isHeadStart = (totalCount / 2) > index; | |
var tempNode = isHeadStart ? head : tail; | |
if (isHeadStart) | |
{ | |
for (var i = 0; i < index; ++i, ++count) | |
{ | |
if (tempNode == tail) | |
{ | |
Console.WriteLine("Add Fail.."); | |
return 0; | |
} | |
tempNode = tempNode.next; | |
} | |
var addNextNode = tempNode.next; | |
addNextNode.prev = addNode; | |
addNode.next = tempNode.next; | |
addNode.prev = tempNode; | |
tempNode.next = addNode; | |
} | |
else | |
{ | |
for (var i = totalCount; i > index; --i, ++count) | |
{ | |
if (tempNode == head) | |
{ | |
Console.WriteLine("Add Fail.."); | |
return 0; | |
} | |
tempNode = tempNode.prev; | |
} | |
var addPrevNode = tempNode.prev; | |
addPrevNode.next = addNode; | |
addNode.next = tempNode; | |
addNode.prev = addPrevNode; | |
tempNode.prev = addNode; | |
} | |
++totalCount; | |
return count; | |
} | |
/// <summary> | |
/// 해당 데이터를 만나면 해당 노드를 삭제한다. | |
/// </summary> | |
/// <param name="removeNode"></param> | |
public int RemoveNode(T removeData, bool matchRemoveAll = false) | |
{ | |
var count = 0; | |
var deleteNode = head; | |
while (deleteNode != tail) | |
{ | |
// 지우려는 데이터가 같다면 | |
if (deleteNode.data.Equals(removeData)) | |
{ | |
// 지우는 로직 | |
var prevNode = deleteNode.prev; | |
var nextNode = deleteNode.next; | |
prevNode.next = nextNode; | |
nextNode.prev = prevNode; | |
deleteNode = null; | |
--totalCount; | |
if (matchRemoveAll) | |
{ | |
count += RemoveNode(removeData, matchRemoveAll); | |
break; | |
} | |
else | |
break; | |
} | |
deleteNode = deleteNode.next; | |
++count; | |
} | |
return count; | |
} | |
/// <summary> | |
/// 원하는 인덱스의 노드를 삭제한다. | |
/// </summary> | |
public int RemoveAt(int index) | |
{ | |
if (index >= totalCount) | |
{ | |
Console.WriteLine("Delete Fail..(index: " + index + ")"); | |
return 0; | |
} | |
var count = 0; | |
var isHeadStart = (totalCount / 2) > index; | |
var deleteNode = isHeadStart ? head.next : tail.prev; | |
if (isHeadStart) | |
{ | |
for (var i = 0; i < index; ++i, ++count) | |
{ | |
if (deleteNode == tail) | |
{ | |
Console.WriteLine("Delete Fail.."); | |
return count; | |
} | |
deleteNode = deleteNode.next; | |
} | |
} | |
else | |
{ | |
for (var i = totalCount -1; i > index; --i, ++count) | |
{ | |
if (deleteNode == head) | |
{ | |
Console.WriteLine("Delete Fail..."); | |
return count; | |
} | |
deleteNode = deleteNode.prev; | |
} | |
} | |
var prevNode = deleteNode.prev; | |
var nextNode = deleteNode.next; | |
prevNode.next = nextNode; | |
nextNode.prev = prevNode; | |
deleteNode = null; | |
--totalCount; | |
return count; | |
} | |
public void PrintNode() | |
{ | |
// HEAD TO TAIL | |
Console.Write("HEAD->"); | |
for (var tempNode = head.next; tempNode != tail; tempNode = tempNode.next) | |
{ | |
Console.Write(tempNode.data + "->"); | |
} | |
Console.WriteLine("TAIL"); | |
// TAIL TO HEAD | |
Console.Write("TAIL->"); | |
for (var tempNode = tail.prev; tempNode != head; tempNode = tempNode.prev) | |
{ | |
Console.Write(tempNode.data + "->"); | |
} | |
Console.WriteLine("HEAD"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment