Add animation player (#1877)

* Add auto slide controller.

* Fix the animation blocks.

* renamed as animation_player

* Bug fixes

* Refine animation player controls
This commit is contained in:
Yudong Jin
2026-03-31 21:24:11 +08:00
committed by GitHub
parent e3c74cfa01
commit 6e600f5ba7
27 changed files with 597 additions and 160 deletions
+10 -10
View File
@@ -11,19 +11,19 @@
- **Удаление вершины**: из матрицы смежности удаляется строка и столбец. При удалении первой строки и первого столбца достигается худший случай, когда требуется "сдвинуть влево вверх" $(n-1)^2$ элементов, поэтому используется $O(n^2)$ времени.
- **Инициализация**: передаются $n$ вершин, затем инициализируется список вершин `vertices` длины $n$ , что требует $O(n)$ времени; после этого инициализируется матрица смежности `adjMat` размера $n \times n$ , что требует $O(n^2)$ времени.
=== "Инициализация матрицы смежности"
=== "<1>"
![Инициализация матрицы смежности, добавление и удаление ребер и вершин](graph_operations.assets/adjacency_matrix_step1_initialization.png)
=== "Добавление ребра"
=== "<2>"
![adjacency_matrix_add_edge](graph_operations.assets/adjacency_matrix_step2_add_edge.png)
=== "Удаление ребра"
=== "<3>"
![adjacency_matrix_remove_edge](graph_operations.assets/adjacency_matrix_step3_remove_edge.png)
=== "Добавление вершины"
=== "<4>"
![adjacency_matrix_add_vertex](graph_operations.assets/adjacency_matrix_step4_add_vertex.png)
=== "Удаление вершины"
=== "<5>"
![adjacency_matrix_remove_vertex](graph_operations.assets/adjacency_matrix_step5_remove_vertex.png)
Ниже приведен код реализации графа на основе матрицы смежности:
@@ -42,19 +42,19 @@
- **Удаление вершины**: требуется пройти по всему списку смежности и удалить все ребра, содержащие указанную вершину; это требует $O(n + m)$ времени.
- **Инициализация**: в списке смежности создаются $n$ вершин и $2m$ ребер; это требует $O(n + m)$ времени.
=== "Инициализация списка смежности"
=== "<1>"
![Инициализация списка смежности, добавление и удаление ребер и вершин](graph_operations.assets/adjacency_list_step1_initialization.png)
=== "Добавление ребра"
=== "<2>"
![adjacency_list_add_edge](graph_operations.assets/adjacency_list_step2_add_edge.png)
=== "Удаление ребра"
=== "<3>"
![adjacency_list_remove_edge](graph_operations.assets/adjacency_list_step3_remove_edge.png)
=== "Добавление вершины"
=== "<4>"
![adjacency_list_add_vertex](graph_operations.assets/adjacency_list_step4_add_vertex.png)
=== "Удаление вершины"
=== "<5>"
![adjacency_list_remove_vertex](graph_operations.assets/adjacency_list_step5_remove_vertex.png)
Ниже приведен код списка смежности. По сравнению с рисунками выше, реальная реализация имеет следующие отличия.
+10 -10
View File
@@ -399,19 +399,19 @@
Как показано на рисунках ниже, мы рассматриваем головной и хвостовой узлы двусвязного списка как голову и хвост двусторонней очереди и одновременно реализуем функции добавления и удаления узлов с обеих сторон.
=== "LinkedListDeque"
=== "<1>"
![Операции enqueue и dequeue для двусторонней очереди на связном списке](deque.assets/linkedlist_deque_step1.png)
=== "push_last()"
=== "<2>"
![linkedlist_deque_push_last](deque.assets/linkedlist_deque_step2_push_last.png)
=== "push_first()"
=== "<3>"
![linkedlist_deque_push_first](deque.assets/linkedlist_deque_step3_push_first.png)
=== "pop_last()"
=== "<4>"
![linkedlist_deque_pop_last](deque.assets/linkedlist_deque_step4_pop_last.png)
=== "pop_first()"
=== "<5>"
![linkedlist_deque_pop_first](deque.assets/linkedlist_deque_step5_pop_first.png)
Код реализации приведен ниже:
@@ -424,19 +424,19 @@
Как показано на рисунках ниже, аналогично реализации обычной очереди на массиве мы также можем использовать кольцевой массив для реализации двусторонней очереди.
=== "ArrayDeque"
=== "<1>"
![Операции enqueue и dequeue для двусторонней очереди на массиве](deque.assets/array_deque_step1.png)
=== "push_last()"
=== "<2>"
![array_deque_push_last](deque.assets/array_deque_step2_push_last.png)
=== "push_first()"
=== "<3>"
![array_deque_push_first](deque.assets/array_deque_step3_push_first.png)
=== "pop_last()"
=== "<4>"
![array_deque_pop_last](deque.assets/array_deque_step4_pop_last.png)
=== "pop_first()"
=== "<5>"
![array_deque_pop_first](deque.assets/array_deque_step5_pop_first.png)
На основе реализации обычной очереди нужно лишь добавить методы добавления в голову очереди и удаления из хвоста:
+6 -6
View File
@@ -368,13 +368,13 @@
Как показано на рисунке ниже, мы можем рассматривать головной узел и хвостовой узел связного списка как голову очереди и хвост очереди соответственно, договорившись, что добавлять узлы можно только в хвост, а удалять - только из головы.
=== "LinkedListQueue"
=== "<1>"
![Операции enqueue и dequeue в реализации очереди на связном списке](queue.assets/linkedlist_queue_step1.png)
=== "push()"
=== "<2>"
![linkedlist_queue_push](queue.assets/linkedlist_queue_step2_push.png)
=== "pop()"
=== "<3>"
![linkedlist_queue_pop](queue.assets/linkedlist_queue_step3_pop.png)
Ниже приведен код реализации очереди на связном списке:
@@ -396,13 +396,13 @@
Можно увидеть, что и `enqueue` , и `dequeue` требуют всего одной операции, а значит обе имеют временную сложность $O(1)$ .
=== "ArrayQueue"
=== "<1>"
![Операции enqueue и dequeue в реализации очереди на массиве](queue.assets/array_queue_step1.png)
=== "push()"
=== "<2>"
![array_queue_push](queue.assets/array_queue_step2_push.png)
=== "pop()"
=== "<3>"
![array_queue_pop](queue.assets/array_queue_step3_pop.png)
Ты можешь заметить еще одну проблему: при непрерывных операциях `enqueue` и `dequeue` значения `front` и `rear` оба движутся вправо, и **когда они доходят до конца массива, дальше сдвигаться уже нельзя**. Чтобы решить эту проблему, можно рассматривать массив как кольцевой массив, у которого начало и конец соединены.
+6 -6
View File
@@ -365,13 +365,13 @@
Как показано на рисунке ниже, для операции `push` достаточно вставить элемент в голову связного списка. Такой способ вставки называется вставкой в голову. Для операции `pop` достаточно удалить головной узел из списка.
=== "LinkedListStack"
=== "<1>"
![Операции push и pop в реализации стека на связном списке](stack.assets/linkedlist_stack_step1.png)
=== "push()"
=== "<2>"
![linkedlist_stack_push](stack.assets/linkedlist_stack_step2_push.png)
=== "pop()"
=== "<3>"
![linkedlist_stack_pop](stack.assets/linkedlist_stack_step3_pop.png)
Ниже приведен пример кода реализации стека на основе связного списка:
@@ -384,13 +384,13 @@
Если реализовывать стек на основе массива, то хвост массива можно рассматривать как вершину стека. Как показано на рисунке ниже, операции `push` и `pop` соответствуют добавлению элемента в конец массива и удалению элемента из конца, обе имеют временную сложность $O(1)$ .
=== "ArrayStack"
=== "<1>"
![Операции push и pop в реализации стека на массиве](stack.assets/array_stack_step1.png)
=== "push()"
=== "<2>"
![array_stack_push](stack.assets/array_stack_step2_push.png)
=== "pop()"
=== "<3>"
![array_stack_pop](stack.assets/array_stack_step3_pop.png)
Поскольку количество элементов, помещаемых в стек, может непрерывно расти, мы можем использовать динамический массив и тем самым не заниматься расширением массива вручную. Ниже приведен пример кода: