1СТРУКТУРЫДАННЫХC#.
ВC#.NET есть много различных структур данных, например Array - одна из самых часто используемых. Однако C# поставляется с гораздо большим количеством таких структур. Необходимо выбирать правильные структуры данных для написания хорошо структурированных и эффективных программ.
Вэтой статье я перечислю встроенные в C# структуры данных, включая новые из
C#.Net 3.5.
1.1 Array.
Возможно самым простой и известной структурой данных является array. В C# array является простым массивом объектов. Для него характерно то, что все его объекты одного типа и их количество фиксировано. Он объявляется и инициализируется следующим образом:
1 [object type][] myArray = new [object type][number of elements]
Некоторые примеры:
1int[] myIntArray = new int[5];
2int[] myIntArray2 = { 0, 1, 2, 3, 4 };
Как можно видеть из приведенного выше примера, массив может инициализироваться пустым или с уже заданными элементами.
1.2 ArrayList.
ArrayList - это динамический массив. Он может иметь любое количество объектов любого типа.
Ниже приведён пример, где ArrayList - массив произвольных объектов, расширяющийся по мере добавления в него новых элементов.
1ArrayList myArrayList = new ArrayList();
2myArrayList.Add(56);
3myArrayList.Add("String");
4myArrayList.Add(new Form());
Недостатком ArrayList является необходимость распаковки его элементов в их оригинальный тип:
1 |
int arrayListValue = (int)myArrayList[0]; |
1.3 List<> (список).
Вкратце, структура данных List<> - это строго типизированный ArrayList. Это тоже динамический массив, но его отличие от ArrayList в том, что List<> должен содержать данные только одного типа:
1List<int> intList = new List<int>();
2intList.Add(45);
3intList.Add(34);
4</int></int>
Поскольку элементы List<> относятся к одному типу их нет необходимости распаковывать при получении:
1 int listValue = intList[0];
Для простых типов данных (int, bool, итд.) использование List<> обеспечивает гораздо большую скорость работы, нежели использованиеArrayList.
1.4 LinkedList<> (двусвязныйсписок).
Теперь совершенно другой тип структуры данных - LinkedList<>. LinkedList<> - это группа объектов, которые вместо того, чтобы индексироваться по ссылке (как, например,Array), расположены в узлах и соединены друг с другом.
LinkedList<> узел содержит три основных значения: сам объект, ссылку на следующий узел, а также ссылки на предыдущий узел.
Какой смысл в такой структуре данных? Её преимущество в том, что добавление элемента в середину списка происходит значительно быстрее, чем в другом типе структуры данных. LinkedList<> также снижает затраты памяти до минимума. С другой стороны, для нахождения элемента, находящегося в середине или в конце списка, требуется довольно много времени.
1LinkedList<int> list = newLinkedList<int>();
2list.AddLast(6);
3</int></int>
Получение значения производится не напрямую, а перебором:
1 list.First.Value
или
1 list.Last.Value
Теперь мы можем перейти к более сложным структурам данных.
1.5 Dictionary<> (словарь).
Структура данных Dictionary<> очень удобна, она позволяет программисту обращаться к значению по её ключевому индексу. Что это значит? ArrayList, к примеру, автоматически создаёт свои "ключи" - числа, 1, 2 и т.д., так, что для доступа к необходимому объекту используется следующая запись:
1 myArrayList[2];
Dictionary<> позволяет использовать ключи любого типа, например:
1Dictionary<string, int=""> myDictionary = new Dictionary<string, int="">();
2myDictionary.Add("one", 1);
3myDictionary.Add("twenty", 20);
4</string,></string,>
Получение значения производится следующим образом:
1 int myInt = myDictionary["one"];
При использовании Dictionary<> нет необходимости метаться между типами. Также никто не запрещает создать Dictionary<> таким образом:
1Dictionary<int, int="" dictionary<string,="">> nestedDictionary =
2new Dictionary<int, int="" dictionary<string,="">>();
3</int,></int,>
То есть вложенные структуры данных Dictionary<> возможны и разрешены.
Я понимаю, что может ввести в заблуждение то, как получить все значения из этой структуры данных, поскольку мы можем не знать закономерности в составлении её ключей. К счастью, это не обязательно, вот пример получения всех данных из
Dictionary<>:
1//List<[same type as index]>
2List<string> keyList = new List<string> (myDictionary.Keys);
3for (int i = 0; i < keyList.Count; i++)
4{
5 |
int myInt = myDictionary[keyList[i]]; |
6}
7</string></string>
Если вы заинтересованы, вы можете прочитать более подробно о C# Dictionary<>.
1.6 Hashtable (хеш-таблица).
Структура данных Hashtable очень похожа на структуру Dictionary<>. Hashtable также принимает пару ключ/значение, но они должны быть объектными ссылками - ссылкой на ключ и ссылкой на сам объект. С приходом .NET 2.0 обобщённые словари
вроде Dictionary<> стали более предпочтительнее, по сравнению со словарями, основанными на типе Object.
Значения в хеш-таблице хранится в порядке, зависящем от хэш-кода ихключа.
1Hashtable myTable = new Hashtable();
1.7HashSet<>.
Структура данных HashSet<> была введена в C# Net 3.5. Эта специфическая
структура данных очень сильно напоминает List<>. В чём же различие? У HashSet<> есть очень важная особенность - она не допускает повторяющихся значений. Например:
1 |
|
HashSet<int> mySet = new HashSet<int>(); |
2 |
|
mySet.Add(3); |
3 |
|
mySet.Add(5); |
4 |
|
mySet.Add(3); |
5 |
|
mySet.Add(10); |
6 |
|
|
7List<int> myListFromSet = mySet.ToList<int>();
8int myInt = myListFromSet[2];
9</int></int></int></int>
Если mySet был бы обычной структурой данных List<>, то индекс 2 должен был вернуть значение 3 (проверьте сами). Но если вы запустите пример, вы увидите, что myInt возвращает значение 10. Это происходит потому, что HashSet<> игнорирует дубликат со значением 3.
Для более подробного изучения вы можете посетить страницу C# HashSet<>.
1.8 Stack и Stack<>(стек).
Класс Stack является одним из многих структур данных в C#, которые напоминают ArrayList. Как и ArrayList, стек имеет методы для добавления и получения данных, но с небольшой разницей в их поведении.
Чтобы добавить в стек данные, необходимо использовать метод Push, который является эквивалентом Add в ArrayList. Получение значения немного отличается. Стек имеет метод Pop, который возвращает и одновременно удаляет последний добавленный объект. Если вы хотите получить последнее значение в стеке без его удаления, используйте метод Peek.
Стек работает по алгоритму LIFO, что расшифровывается как Last-In-First-Out (последним пришёл - первым обслужен). Эта специфическая структура данных будет полезна, если вам необходимо вернуться той же дорогой, так сказать.
Есть два вида объявления стека в C#:
1Stack stack = new Stack();
2Stack<string> stack = new Stack<string>();
3</string></string>