Форум программистов, компьютерный форум, киберфорум
Haskell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 14.06.2015
Сообщений: 7

Бинарное дерево с помеченными вершинами

22.06.2015, 22:38. Показов 2239. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!

Задача:
Дано бинарное дерево, некоторые вершины которого помечены. Проверить, находятся ли последние на одном пути от корня к листу

Как новичок, хотел бы попросить максимально простой код, буду благодарен любым пояснениям!
Заранее спасибо!))
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.06.2015, 22:38
Ответы с готовыми решениями:

Исходное бинарное дерево превратить в бинарное дерево поиска, при этом сохранив его структуру
Помогите, не могу понять!( Нужно исходное бинарное дерево превратить в бинарное дерево поиска, при этом сохранив его структуру. вот...

Преобразовать идеальное бинарное дерево в бинарное дерево поиска
Всем привет, я создал идельное бинарное дерево и написал к нему функции. Как мне теперь можно преобразовать его в бинарное дерево поиска?...

Бинарное дерево: как происходит добавления элемента в дерево с двумя параметрами
Здравствуйте! Прошу помощи у опытных программистов...)))) Есть класс дерево: class class1 { public class Tree ...

24
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,989
Записей в блоге: 32
22.06.2015, 22:59
А что такое максимально простой код? Где меньше всего символов? Тогда с deriving Foldable чувствую можно нарисовать, только функцию свертки написать в 2 строчки явно.

ЗЫ я вам в соседнем разделе привел 2 варианта кода для этой же вашей задачи.
0
Модератор
 Аватар для Curry
5156 / 3476 / 536
Регистрация: 01.06.2013
Сообщений: 7,535
Записей в блоге: 9
22.06.2015, 23:13
Haskell
1
2
3
4
5
6
7
8
9
10
11
data BinTree = BinTree Bool BinTree BinTree | Empty
 
onePath :: BinTree -> Bool
onePath (Empty) = False
onePath (BinTree False _ _) = False
onePath (BinTree _ Empty Empty) = True
onePath (BinTree _ l r) = onePath l /= onePath r
 
main = print $ onePath $ BinTree True (BinTree False Empty Empty)
                                      (BinTree True (BinTree False Empty Empty)
                                                    (BinTree True Empty (BinTree True Empty Empty)))
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,989
Записей в блоге: 32
22.06.2015, 23:18
KolodeznyDiver, хотел написать что ваш код не будет работать, а потом подумал, что дело в великом и могучем русском языке - я понял задание так, что если например, у нас из огромного ветвистого дерева помечено всего 2 вершины, но существует путь без возвратов, включающий их, то результат должен быть тру.
0
Модератор
 Аватар для Curry
5156 / 3476 / 536
Регистрация: 01.06.2013
Сообщений: 7,535
Записей в блоге: 9
22.06.2015, 23:25
Цитата Сообщение от _Ivana Посмотреть сообщение
Тогда с deriving Foldable чувствую можно нарисовать
Цитата Сообщение от _Ivana Посмотреть сообщение
я понял задание так
Хоть так, хоть эдак. Я не представляю, как, с помощью Data.Foldable такое сделать. Но, может, я ошибаюсь.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,989
Записей в блоге: 32
23.06.2015, 00:19
Лучший ответ Сообщение было отмечено Shelb как решение

Решение

Да, переоценил я возможности дерайва Фолдабла - катаморфизмы он не дерайвит, потому что работает на общем типе данных. Ну не страшно, написал руками 2 строчки - не честный фолд, конечно, но можно и честный, только лямбд добавится.
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
data T a = T a (T a) (T a) | N
 
-- не отдерайвился такой-сякой, пришлось руками писать
myfold f N = 0
myfold f (T v l r) = f v (myfold f l) (myfold f r)
 
f v l r = case (l+r) of
    0 -> fromEnum v
    1 -> 1
    _ -> 2
 
test t = case myfold f t of
    0 -> "No mark nodes"
    1 -> "All marked nodes are on one path"
    _ -> "There are marked nodes on different paths"
 
t1 = T True (T False N N)
            (T False (T True N N)
                     (T True N (T True N N)))
t2 = T True (T False N N)
            (T False (T False N N)
                     (T True N (T True N N)))
main = do
    print $ test t1
    print $ test t2
 
"There are marked nodes on different paths"
"All marked nodes are on one path"
2
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
23.06.2015, 01:09
Я так понимаю, что требуется проверить существование пути, на котором находятся все помеченные вершины.
0
Модератор
 Аватар для Curry
5156 / 3476 / 536
Регистрация: 01.06.2013
Сообщений: 7,535
Записей в блоге: 9
23.06.2015, 01:25
Цитата Сообщение от _Ivana Посмотреть сообщение
Да, переоценил я возможности дерайва Фолдабла
Не deriving Foldable, а сам Foldable переоценили. Даже если самому написать инстанс, всё равно, Foldable выполняет проходы по всем элементам некой структуры, выполняя чтото для каждого элемента, но не учитывая связи между элементами структуры. Может, что то и можно наколхозить, но, выйдет сложнее чем без него.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,989
Записей в блоге: 32
23.06.2015, 03:10
KolodeznyDiver, вы правы. Хотя, может именно для библиотечного бинарного дерева и есть уже готовая свертка с учетом левого и правого узлов.

Добавлено через 1 час 27 минут
Вот, собственно, апофигей сути (ТС же просил попроще ) - "котоморфизм всемогущий" ((С) DeeMon про трансдьюсеры в Clojure). Копипаста кота (без особого понимания) из http://traditio-ru.org/wiki/%D... 0%B7%D0%BC
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
data T a = T a (T a) (T a) | N
 
type TreeAlgebra a r = (r, a -> r -> r -> r)
 
foldTree :: TreeAlgebra a r -> T a -> r
foldTree (f, g) N         = f
foldTree (f, g) (T x l r) = g x (foldTree (f, g) l) (foldTree (f, g) r)
 
testMarkPath :: TreeAlgebra Bool Int
testMarkPath = (0, \v l r -> if l+r==0 then fromEnum v else l+r)
 
test t = case foldTree testMarkPath t of
    0 -> "No mark nodes"
    1 -> "All marked nodes are on one path"
    _ -> "There are marked nodes on different paths"
 
t1 = T True (T False N N)
            (T False (T True N N)
                     (T False N (T True N N)))
t2 = T True (T False N N)
            (T False (T False N N)
                     (T True N (T True N N)))
main = do
    print $ test t1
    print $ test t2
ЗЫ и вполне возможно эта красота уже есть в какой-то библиотеке. А вот здесь http://habrahabr.ru/post/57503/ рассказано попроще, причем реализовано без создания типов данных, так что я этот вариант даже на своем бестиповом лискрипте реализовал - и работает, деревья реализованы как абстрактный тип данных через замыкания с интерфейсными функциями конструирования-доступа.

Добавлено через 12 минут
Вгляделся я в котоморфизм и узнал в нем моего простого кота парой постов выше, только в функцию свертки дерева передается не только функция преобразования, а и в паре с ней начальное значение для терминальных кейсов - тот самый 0. И если бы я сам своего кота делал универсальным, то сделал бы точно также.
2
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
23.06.2015, 03:45
А есть в Хаскеле (GHCi) готовый тип Бинарное Дерево?

А как функцию a -> b -> m c поднять до m a -> m b -> m c ?
Вобщем, я не знаю, как элегантно поднять g1, поэтому кроме g2 написал ещё и f2

Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import Control.Applicative
 
data T a = T a (T a) (T a) | N
 
myfold f N = Just False
myfold f (T v l r) = f v (myfold f l) (myfold f r)
 
f2 v l r = (||v) <$> case liftA2 (&&) l r of { Just True -> Nothing; _ -> liftA2 (||) l r }
 
g1 a b = if a && b then Nothing else Just (a || b)
g2 v l r = maybe Nothing ((||v) <$>) $ g1 <$> l <*> r
 
t1 = T True (T False N N)
            (T False (T True N N)
                     (T True N (T True N N)))
t2 = T True (T False N N)
            (T False (T False N N)
                     (T True N (T True N N)))
main = do
    print $ myfold f2 t1
    print $ myfold f2 t2
    print $ myfold g2 t1
    print $ myfold g2 t2
0
Модератор
 Аватар для Curry
5156 / 3476 / 536
Регистрация: 01.06.2013
Сообщений: 7,535
Записей в блоге: 9
23.06.2015, 11:25
Цитата Сообщение от Shamil1 Посмотреть сообщение
как функцию a -> b -> m c поднять до m a -> m b -> m c ?
Haskell
1
2
3
4
import Control.Monad 
 
lift2':: Monad m => (a -> b -> m c) -> m a -> m b -> m c
lift2' f a1 a2 = join $ liftM2 f a1 a2
Я понимаю, что Вы тренируетесь с функторами. Но использовать один ADT из двух вариантов - Bool, вложенный в другой двухвариантный - Maybe. Напрашивается один трёхвариантный сделать, вроде
Haskell
1
data PassState = Pass | NoPass | Hmm
1
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
23.06.2015, 16:58
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Но использовать один ADT из двух вариантов - Bool, вложенный в другой двухвариантный - Maybe. Напрашивается один трёхвариантный сделать
Идея была другая:

Мы сворачиваем дерево, но есть ситуация, когда свёртка бессмысленна (метки в двух разных ветвях дерева), поэтому Maybe. В данном случае задача простая, поэтому (внутри) Bool, но задача могла бы быть немного сложнее (например, нужно вернуть путь, содержащий все метки).

p.s. А liftM2 чем от liftA2 отличается?

Добавлено через 38 минут

Не по теме:

могу я записать в бесточечном стиле?

Haskell
1
f a b = f1 (f2 a b)

0
23.06.2015, 17:05

Не по теме:

Haskell
1
f = f1 . f2
не работает?

0
Модератор
 Аватар для Curry
5156 / 3476 / 536
Регистрация: 01.06.2013
Сообщений: 7,535
Записей в блоге: 9
23.06.2015, 17:09
Цитата Сообщение от Shamil1 Посмотреть сообщение
liftM2 чем от liftA2 отличается
одна для монад, другая для аппликативных функторов.
Цитата Сообщение от Shamil1 Посмотреть сообщение
могу я записать в бесточечном стиле? f a b = f1 (f2 a b)
Это, как раз точечный стиль. Бесточечный, он, как раз бывает с точками. (это не шутка)
0
23.06.2015, 17:29

Не по теме:

Цитата Сообщение от _Ivana Посмотреть сообщение
f = f1 . f2
Получаем f a b = (f1 (f2 a)) b

Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Это, как раз точечный стиль. Бесточечный, он, как раз бывает с точками. (это не шутка)
Путаюсь в терминологии. Хочу записать "без аргументов": f = ...

0
Модератор
 Аватар для Curry
5156 / 3476 / 536
Регистрация: 01.06.2013
Сообщений: 7,535
Записей в блоге: 9
23.06.2015, 17:35
Haskell
1
2
3
4
5
6
7
8
f1:: a -> b
f1 = undefined
 
f2:: a -> b -> c
f2 = undefined
 
f:: a -> b -> c
f = f1 . f2
0
23.06.2015, 17:41

Не по теме:

Эта-редукция, понимаешь....

0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
23.06.2015, 20:57
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Haskell
1
2
3
4
5
6
f1:: a1 -> b1
f1 = undefined
f2:: a2 -> b2 -> c2
f2 = undefined
f:: a -> b -> c
f = f1 . f2
Вот только a b c тут разные. Например, a1 = (b2 -> c2)
Попробуйте так скомпилировать:
Haskell
1
2
3
4
5
6
7
8
f1:: Int -> Int
f1 = undefined
 
f2:: Int -> Int -> Int
f2 = undefined
 
f:: Int -> Int -> Int
f = f1 . f2
сообщение компилятора
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Current.hs:18:5:
    Couldn't match type ‘Int’ with ‘Int -> Int’
    Expected type: Int -> Int -> Int
      Actual type: Int -> Int
    In the first argument of ‘(.)’, namely ‘f1’
    In the expression: f1 . f2
 
Current.hs:18:10:
    Couldn't match type ‘Int -> Int’ with ‘Int’
    Expected type: Int -> Int
      Actual type: Int -> Int -> Int
    Probable cause: ‘f2’ is applied to too few arguments
    In the second argument of ‘(.)’, namely ‘f2’
    In the expression: f1 . f2
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,989
Записей в блоге: 32
23.06.2015, 21:26
Shamil1, правда ваша, я был у заказчиков и не проверил свой простой вариант. Тогда ловите такой, раз хотите бесточечную нотацию
Haskell
1
f = (f1 .) . f2
Добавлено через 9 минут
Ну или вот так, что то же самое, только симметричнее
Haskell
1
f = (.) f1 . f2
2
Модератор
 Аватар для Curry
5156 / 3476 / 536
Регистрация: 01.06.2013
Сообщений: 7,535
Записей в блоге: 9
23.06.2015, 21:40
Цитата Сообщение от _Ivana Посмотреть сообщение
f = (.) f1 . f2
Неплохо, но, по кол-ву значков меньше банальной f x = f1 . f2 x
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.06.2015, 21:40
Помогаю со студенческими работами здесь

Бинарное дерево. Удалить из дерева часть вершин так, чтобы оставшееся дерево стало пирамидой
Дано бинарное дерево. Удалить из дерева часть вершин так, чтобы оставшееся дерево стало пирамидой.

Бинарное дерево
дано целочисленнное бинарное дерево. найти: а)количество вершин дереваж б)значение самой левой вершины в правом поддереве в)...

Бинарное дерево
Нужно записать в дерево и вывести в форматированном виде каталог файлов(типа windows) на вход даны имена файлов вида c:\win\1 ...

Бинарное дерево
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;conio.h&gt; int last; void add(double volue) { //double *arr = new...

Бинарное дерево
Объясните пжлст почему не работает программа...при вводе файла пишет -842150451 /*Дан адрес P1 вершины дерева — записи типа TNode, ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG-файла с альфа-каналом с помощью библиотеки SDL3_image на Android
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru