forked from wangzheng0822/algo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add single linked list and lru cache implementation
- Loading branch information
1 parent
6b0594d
commit 1e4b89c
Showing
6 changed files
with
789 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using System; | ||
|
||
namespace _06_linked_list | ||
{ | ||
public class BaseLinkedListTests | ||
{ | ||
protected void PrintList<T> (SingleLinkedList<T> list) where T : IComparable<T> | ||
{ | ||
if (list == null) return; | ||
|
||
var p = list.First; | ||
while (p != null) | ||
{ | ||
System.Console.WriteLine (p.Value); | ||
p = p.Next; | ||
} | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
|
||
namespace _06_linked_list | ||
{ | ||
public class LRULinkedListTests : BaseLinkedListTests | ||
{ | ||
[Fact] | ||
public void LRU_Set_Value_When_Not_Existed() | ||
{ | ||
var lru = new LRULinkedList(); | ||
|
||
lru.Set(1); | ||
lru.Set(3); | ||
lru.Set(5); | ||
lru.Set(7); | ||
lru.Set(9); | ||
|
||
var list = lru.GetCachedList(); | ||
|
||
PrintList(list); | ||
|
||
Assert.Equal(9, list.First.Value); | ||
} | ||
|
||
[Fact] | ||
public void LRU_Set_Value_When_Existed() | ||
{ | ||
var lru = new LRULinkedList(); | ||
|
||
lru.Set(1); | ||
lru.Set(3); | ||
lru.Set(5); | ||
lru.Set(7); | ||
lru.Set(3); | ||
|
||
var list = lru.GetCachedList(); | ||
|
||
PrintList(list); | ||
|
||
Assert.Equal(3, list.First.Value); | ||
} | ||
|
||
[Fact] | ||
public void LRU_Set_Value_When_Full() | ||
{ | ||
var lru = new LRULinkedList(5); | ||
|
||
lru.Set(1); | ||
lru.Set(3); | ||
lru.Set(5); | ||
lru.Set(7); | ||
lru.Set(9); | ||
lru.Set(8); | ||
|
||
var list = lru.GetCachedList(); | ||
|
||
PrintList(list); | ||
|
||
Assert.Equal(8, list.First.Value); | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
namespace _06_linked_list | ||
{ | ||
/// <summary> | ||
/// 使用单链表实现LRU缓存淘汰算法 | ||
/// </summary> | ||
/// <remarks> | ||
/// 思路: | ||
/// 维护一个有序单链表,越是靠近链尾的数据是最早访问的。当有一个新的数据被访问时, | ||
/// 1. 如果数据在缓存中,则将其从原位置删除,然后插入到表头; | ||
/// 2. 如果数据不在缓存中,有两种情况: | ||
/// 1) 链表未满,则将数据插入到表头; | ||
/// 2) 链表已满,则删除尾结点,将新数据插入到表头。 | ||
/// </remarks> | ||
public class LRULinkedList | ||
{ | ||
private readonly SingleLinkedList<int> _cachedList = new SingleLinkedList<int>(); | ||
private readonly int _capacity; | ||
|
||
/// <summary> | ||
/// 构造函数 | ||
/// </summary> | ||
/// <param name="capacity">缓存容量</param> | ||
public LRULinkedList(int capacity = 10) | ||
{ | ||
_capacity = capacity; | ||
} | ||
|
||
/// <summary> | ||
/// 存储缓存数据 | ||
/// </summary> | ||
/// <param name="val"></param> | ||
public void Set(int val) | ||
{ | ||
var deletedNode = _cachedList.Delete(value: val); | ||
|
||
// 数据在缓存中存在,从原位置删除,然后插入到表头 | ||
if (deletedNode != null) | ||
{ | ||
_cachedList.Insert(1, val); | ||
return; | ||
} | ||
|
||
// 数据不存在 | ||
if (_cachedList.Length != _capacity) | ||
{ | ||
// 链表未满 | ||
_cachedList.Insert(1, val); | ||
} | ||
else | ||
{ | ||
// 链表已满,删除尾结点,将新数据插入到头部 | ||
_cachedList.Delete(_cachedList.Length); | ||
_cachedList.Insert(1, val); | ||
} | ||
} | ||
|
||
public SingleLinkedList<int> GetCachedList() | ||
{ | ||
return _cachedList; | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.