upload
This commit is contained in:
358
MyList.cs
Normal file
358
MyList.cs
Normal file
@@ -0,0 +1,358 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Prac8
|
||||
{
|
||||
public class MyList<T> : IEnumerable<T>
|
||||
{
|
||||
private const int DefaultCapacity = 4;
|
||||
private T[] _items;
|
||||
private int _count;
|
||||
|
||||
public MyList(int capacity = DefaultCapacity)
|
||||
{
|
||||
if (capacity < 1)
|
||||
{
|
||||
capacity = DefaultCapacity;
|
||||
}
|
||||
|
||||
_items = new T[capacity];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
public int Count => _count;
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get => Get(index);
|
||||
set
|
||||
{
|
||||
ValidateIndex(index);
|
||||
_items[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
EnsureCapacity();
|
||||
_items[_count] = item;
|
||||
_count++;
|
||||
}
|
||||
|
||||
public void Insert(int index, T item)
|
||||
{
|
||||
ValidateInsertIndex(index);
|
||||
EnsureCapacity();
|
||||
|
||||
for (int i = _count; i > index; i--)
|
||||
{
|
||||
_items[i] = _items[i - 1];
|
||||
}
|
||||
|
||||
_items[index] = item;
|
||||
_count++;
|
||||
}
|
||||
|
||||
public void AddRange(MyList<T> otherList)
|
||||
{
|
||||
if (otherList == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(otherList), "Другой список не должен быть null.");
|
||||
}
|
||||
|
||||
MyList<T> source = CreateSafeCopy(otherList);
|
||||
EnsureCapacityFor(source.Count);
|
||||
|
||||
foreach (T item in source)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertRange(int index, MyList<T> otherList)
|
||||
{
|
||||
ValidateInsertIndex(index);
|
||||
|
||||
if (otherList == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(otherList), "Другой список не должен быть null.");
|
||||
}
|
||||
|
||||
if (otherList.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MyList<T> source = CreateSafeCopy(otherList);
|
||||
EnsureCapacityFor(source.Count);
|
||||
|
||||
for (int i = _count - 1; i >= index; i--)
|
||||
{
|
||||
_items[i + source.Count] = _items[i];
|
||||
}
|
||||
|
||||
int insertPosition = index;
|
||||
foreach (T item in source)
|
||||
{
|
||||
_items[insertPosition] = item;
|
||||
insertPosition++;
|
||||
}
|
||||
|
||||
_count += source.Count;
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
ValidateIndex(index);
|
||||
|
||||
for (int i = index; i < _count - 1; i++)
|
||||
{
|
||||
_items[i] = _items[i + 1];
|
||||
}
|
||||
|
||||
_count--;
|
||||
_items[_count] = default(T);
|
||||
}
|
||||
|
||||
public void RemoveLast()
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("Нельзя удалить последний элемент из пустого списка.");
|
||||
}
|
||||
|
||||
_count--;
|
||||
_items[_count] = default(T);
|
||||
}
|
||||
|
||||
public void RemoveRange(int firstIndex, int secondIndex)
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("Список пуст.");
|
||||
}
|
||||
|
||||
ValidateIndex(firstIndex);
|
||||
ValidateIndex(secondIndex);
|
||||
|
||||
if (firstIndex > secondIndex)
|
||||
{
|
||||
throw new ArgumentException("Первый индекс не может быть больше второго.");
|
||||
}
|
||||
|
||||
int removeCount = secondIndex - firstIndex + 1;
|
||||
|
||||
for (int i = firstIndex; i < _count - removeCount; i++)
|
||||
{
|
||||
_items[i] = _items[i + removeCount];
|
||||
}
|
||||
|
||||
for (int i = _count - removeCount; i < _count; i++)
|
||||
{
|
||||
_items[i] = default(T);
|
||||
}
|
||||
|
||||
_count -= removeCount;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
for (int i = 0; i < _count; i++)
|
||||
{
|
||||
_items[i] = default(T);
|
||||
}
|
||||
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
public T Get(int index)
|
||||
{
|
||||
ValidateIndex(index);
|
||||
return _items[index];
|
||||
}
|
||||
|
||||
public void Print()
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
Console.WriteLine("Список пуст.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < _count; i++)
|
||||
{
|
||||
Console.WriteLine($"[{i}] {_items[i]}");
|
||||
}
|
||||
}
|
||||
|
||||
public T Find(Predicate<T> match)
|
||||
{
|
||||
if (match == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(match), "Предикат не должен быть null.");
|
||||
}
|
||||
|
||||
for (int i = 0; i < _count; i++)
|
||||
{
|
||||
if (match(_items[i]))
|
||||
{
|
||||
return _items[i];
|
||||
}
|
||||
}
|
||||
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public void EnsureCapacity()
|
||||
{
|
||||
if (_count < _items.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int newCapacity = _items.Length == 0 ? DefaultCapacity : _items.Length * 2;
|
||||
Array.Resize(ref _items, newCapacity);
|
||||
}
|
||||
|
||||
public void Sort(int index)
|
||||
{
|
||||
if (index != 0 && index != 1)
|
||||
{
|
||||
throw new ArgumentException("Для сортировки используйте 1 - по возрастанию или 0 - по убыванию.");
|
||||
}
|
||||
|
||||
if (_count < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Comparer<T> comparer = Comparer<T>.Default;
|
||||
bool ascending = index == 1;
|
||||
|
||||
for (int i = 0; i < _count - 1; i++)
|
||||
{
|
||||
int selectedIndex = i;
|
||||
|
||||
for (int j = i + 1; j < _count; j++)
|
||||
{
|
||||
int compareResult = comparer.Compare(_items[j], _items[selectedIndex]);
|
||||
|
||||
if ((ascending && compareResult < 0) || (!ascending && compareResult > 0))
|
||||
{
|
||||
selectedIndex = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedIndex != i)
|
||||
{
|
||||
T temp = _items[i];
|
||||
_items[i] = _items[selectedIndex];
|
||||
_items[selectedIndex] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Reverse()
|
||||
{
|
||||
int left = 0;
|
||||
int right = _count - 1;
|
||||
|
||||
while (left < right)
|
||||
{
|
||||
T temp = _items[left];
|
||||
_items[left] = _items[right];
|
||||
_items[right] = temp;
|
||||
left++;
|
||||
right--;
|
||||
}
|
||||
}
|
||||
|
||||
public void Distinct()
|
||||
{
|
||||
if (_count < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
|
||||
T[] uniqueItems = new T[Math.Max(DefaultCapacity, _count)];
|
||||
int uniqueCount = 0;
|
||||
|
||||
for (int i = 0; i < _count; i++)
|
||||
{
|
||||
bool exists = false;
|
||||
|
||||
for (int j = 0; j < uniqueCount; j++)
|
||||
{
|
||||
if (comparer.Equals(_items[i], uniqueItems[j]))
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
uniqueItems[uniqueCount] = _items[i];
|
||||
uniqueCount++;
|
||||
}
|
||||
}
|
||||
|
||||
_items = uniqueItems;
|
||||
_count = uniqueCount;
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
for (int i = 0; i < _count; i++)
|
||||
{
|
||||
yield return _items[i];
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
private void ValidateIndex(int index)
|
||||
{
|
||||
if (index < 0 || index >= _count)
|
||||
{
|
||||
throw new IndexOutOfRangeException("Индекс находится вне границ списка.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateInsertIndex(int index)
|
||||
{
|
||||
if (index < 0 || index > _count)
|
||||
{
|
||||
throw new IndexOutOfRangeException("Индекс для вставки находится вне границ списка.");
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureCapacityFor(int additionalItems)
|
||||
{
|
||||
while (_count + additionalItems > _items.Length)
|
||||
{
|
||||
int newCapacity = _items.Length == 0 ? DefaultCapacity : _items.Length * 2;
|
||||
Array.Resize(ref _items, newCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
private static MyList<T> CreateSafeCopy(MyList<T> source)
|
||||
{
|
||||
MyList<T> copy = new MyList<T>(Math.Max(DefaultCapacity, source.Count));
|
||||
foreach (T item in source)
|
||||
{
|
||||
copy.Add(item);
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user