Упорядоченный список
Для создания отсортированного списка метод добавления элемента AddSort() должен сначала найти элемент, за которым будет вставлен новый элемент:
Листинг 8.10. Метод AddSort()
public void AddSort(int inf)
{
if (head != null)
{
MyNode q = head;
if (inf < q.inf)
{ // вставить перед головой
MyNode p = new MyNode(inf, q);
head = p;
}
else
{ // найти место вставки
while ((q.next!=null)&&(q.next.inf<=inf))
q = q.next;
MyNode p = new MyNode(inf, q.next);
q.next = p;
}
}
else
head = new MyNode(inf,null); // список пуст
count++;
}
Частотный словарь
В качестве примера использования упорядоченного списка рассмотрим построение частотного словаря. Эта задача возникает при анализе некоторого текста, когда необходимо определить, сколько и каких слов в нем встретилось, то есть определить частоту появления каждого слова. Решение заключается в следующем.
Если слово встречается первый раз, то оно заносится в список. Если такое слово уже есть в списке, то увеличивается счетчик появления этого слова. Поэтому список опишем следующим образом:
Листинг 8.11. Класс MyNodeStr
class MyNodeStr
{
public string inf; // слово
public MyNodeStr next;
public int count; // счетчик слов
// Конструктор
public MyNodeStr(string inf, MyNodeStr next)
{
this.inf = inf;
this.next = next;
this.count = 1;
}
public void AddCount()
// метод увеличения счетчика
{ count++; }
}
Сначала необходимо осуществить поиск слова в списке. Для переменных типа string упорядочение понимается в лексикографическом смысле, то есть роза меньше, чем роса, а роса меньше, чем соловей. В C# нельзя сравнивать строки s1 и s2 операциями отношения <,>. Вместо операций отношения необходимо использовать метод класса string:
int string.CompareOrdinal(s1, s2)
Этот метод возвращает отрицательное значение, если s1<s2, равное 0, если s1=s2, и положительное, если s1>s2.
В основе алгоритма лежит процедура Insert(), всегда вставляющая новый элемент в упорядоченный список. Однако теперь требуется дополнительная проверка на наличие в списке слова. Далее для сравнения приведены блок-схемы алгоритмов вставки в упорядоченный список (рис. 8.5, а) и обработки слова в списке частотного словаря (рис. 8.5, б). Дополнительные действия выделены серым цветом.
а б
Рис. 8.5. Блок-схемы алгоритмов вставки в упорядоченный список (а) и обработки слова в списке частотного словаря (б)
Программные дополнения учтены в процедуре AddSort, приведенной в листинге 8.12.
Листинг 8.12. Вставка слова в список частотного словаря
public void AddSort(string inf)
{
if (head != null)
{
MyNodeStr q = head;
int k = string.CompareOrdinal(inf, q.inf);
// -1:s1<s2 0:s1=s2 1:s1>s2
if (k<=0)
if (k == 0)
q.AddCount();
else { // вставить перед головой
MyNodeStr p = new MyNodeStr(inf, q);
head = p;
}
else
{
MyNodeStr r; // поиск: inf >= q.inf
do
{
r = q;
q = q.next;
if (q != null)
k = string.CompareOrdinal(q.inf, inf);
}
while ((q!=null) && (k<0));
if (q != null)
if (k == 0)
q.AddCount();
else
{ // вставить между r и q
MyNodeStr p = new MyNodeStr(inf, q);
r.next = p;
}
else
{ // вставить за r
MyNodeStr p = new MyNodeStr(inf, null);
R .next = p;
}
}
}
else // список пуст
head = new MyNodeStr(inf,null);
count++;
}
Для вызова метода AddSort() в коде Main() вставим строки:
Листинг 8.13. Вызов метода AddSort()
MyListWord myListWord = new MyListWord();
string[] s = {"bbb", "ccc", "aaa", "bbb", "aaa" ,
"ccc", "bbb"};
for (int i = 0; i <= s.Length - 1; i++ )
myListWord.AddSort(s[i]);
myListWord.Printer();
