ПОНЯТНО О Visual Basic NET (том 3)

       

Работаем с TreeView в коде


Задача. Подсчитать, сколько человек в родословной имеют имя длиной в 4 буквы.

Задача нетривиальная. Ведь программа должна пробежаться по всем вершинам, то есть по всем коллекциям вершин. Мы с вами пробежались разик по коллекции корней в процедуре Form1_Load в предыдущем подразделе. Но как заставить программу перепрыгнуть от отца к сыну, затем к внуку и так далее на неизвестную глубину и там делать свое дело? Это вопрос. И здесь нам на выручку приходит рекурсия (15.9). Если вы не поняли, как она работает, сейчас самое время вернуться назад и разобраться, потому что иначе вы не поймете то, что написано дальше.

Программа:

Dim K As Integer = 0            'Счетчик 4-буквенных имен

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Посчитай(TreeView1)

        Debug.WriteLine(K)

End Sub

Sub Посчитай(ByVal Вершина As Object)

        Dim Дочь As TreeNode

        For Each Дочь In Вершина.Nodes

            If Len(Дочь.Text) = 4 Then K = K + 1

            Посчитай(Дочь)



        Next

End Sub

Как видите, программа получилась удивительно короткой. Такова рекурсия.

Пояснения: Если объяснять подробно, то придется давать такое же длинное ступенчатое пояснение, как для факториала. Поясню коротко. Вот процедура Посчитай «входит» в какую-нибудь очередную вершину, которая является ее параметром. Цикл

        For Each Дочь In Вершина.Nodes

заставляет ее для каждой своей дочерней вершины выполнить два оператора. Первый –

            If Len(Дочь.Text) = 4 Then K = K + 1

собственно выполняет весь подсчет, а именно, если имя дочери состоит из 4 букв, то увеличивает счетчик. Второй оператор

            Посчитай(Дочь)

и есть главный инструмент рекурсии. Он заставляет VB посчитать дочь точно так же, как только что шел подсчет для ее родителя. Там VB обнаружит внуков и так, по механизму рекурсии, обежит всех потомков вершины безо всякой головной боли с нашей стороны.

Чтобы просчитать все дерево, нам достаточно запустить процедуру Посчитай, параметром которой служила бы не вершина, а все дерево. Это мы как раз и делаем, щелчком по кнопке запуская процедуру Посчитай(TreeView1).


Наиболее дотошные спросят: А почему я не написал заголовок так:

Sub Посчитай(ByVal Вершина As TreeNode)

Только потому, что TreeView не является объектом класса TreeNode. Пришлось объявлять вершину более общим классом..

Задания. Когда мы вычисляли факториал, мы все усилия потратили на объяснение компьютеру, что это такое, а программа родилась как бы сама собой из этого объяснения. Если при решении нижеприведенных задач вы поступите так же, у вас появится шанс решить их правильно.

Задание 15.          

Пометить желтым фоном родителей, у которых ровно 2 ребенка.

Задание 16.          

Пометить синим шрифтом родителей, у которых среди детей ровно 2 ребенка, имя которых начинается на букву «Л».

Задание 17.          

Бездетным создать по два ребенка, имена которых получаются из имени родителя добавлением соответственно 1 и 2.

Задание 18.          

Если имя вершины начинается на букву «Ф», пометить ее и все ее потомство во всех поколениях светло-зеленым фоном. Подсказка: Здесь нужны две рекурсивные процедуры.


Содержание раздела