0 / 0 / 0
Регистрация: 14.02.2020
Сообщений: 7

Сортировка слиянием

17.03.2020, 15:18. Показов 6551. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите разобраться, почему не работает.
Написал сортировку слиянием через 2 функции: одна сортирует и объединяет списки, другая дробит список, пока в нём не останется только 1 элемент.
Первая функция работает нормально.

Python
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
29
30
31
32
33
34
35
36
37
38
39
def merge(list1, list2):
    i = k = 0
    list_res = []
    while i < len(list1) and k < len(list2):
        if list1[i] <= list2[k]:
            list_res.append(list1[i])
            i += 1
        else:
            list_res.append(list2[k])
            k += 1
    while i < len(list1):
        list_res.append(list1[i])
        i += 1
    while k < len(list2):
        list_res.append(list2[k])
        k += 1
    return list_res
 
 
def sort(original_list: list):
    if len(original_list) <= 1:
        return
    middle = len(original_list) // 2
    left = original_list[:middle]
    right = original_list[middle:]
    print('left:', left, 'right:', right)
    sort(left)
    sort(right)
    temp_list = merge(left, right)
    print('temp_list:', temp_list)
    # original_list = list(temp_list[i] for i in range(len(original_list))) - почему оно так не работает?!
    for i in range(len(original_list)):                                  # - а так работает?!
        original_list[i] = temp_list[i]
    print('original_list:', original_list)
    return original_list
 
 
 
print(sort([5, 4, 3, 2]))
не могу понять, почему не работает через присвоение типа "original_list = ", а работает только тогда, когда непосредственно по индексам меняешь значения.
Соответственно не прокатывают и другие варианты, которые первыми пробовал:
original_list = temp_list[:]
original_list = list(temp_list)

во второй функции повставлял принты, чтобы видеть как и что происходит.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.03.2020, 15:18
Ответы с готовыми решениями:

Сортировка слиянием
Помогите, пожалуйста, с ошибкой File &quot;Untitled3.py&quot;, line 43, in &lt;module&gt; print(*merge_sort(a)) TypeError: print() argument...

Сортировка слиянием
Нужно создать код (сортировка слиянием). Подойдёт ли этот? def merge_sort(alist, start, end): '''Sorts the list from indexes start...

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

9
Модератор
Эксперт Python
 Аватар для Fudthhh
2695 / 1601 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
17.03.2020, 15:23
ncmps, а почему бы не использовать стандартный метод list.copy()?
0
0 / 0 / 0
Регистрация: 14.02.2020
Сообщений: 7
17.03.2020, 15:35  [ТС]
DmFat, да результат тот же, я уже все варианты перегуглил. Если стоит "original_list = ", то не работает. Только изменения конкретно по индексам работает. При чём в дебагере по шагам проверяю и сами методы работают, т.е. original_list изменяется, как положено, но в return всё равно выходит не то значение. Т.е., например, в лист left должно возвращаться по итогу [4, 5], как это работает в случае, если по индексам пробегаем, а вот если через "равно", то возвращается предыдущее значение [5, 4] и поэтому на выходе получается неправильно.
0
Модератор
Эксперт Python
 Аватар для Fudthhh
2695 / 1601 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
17.03.2020, 15:57
ncmps,
Решение (более акуратно, но это лично мое мнение):
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# -*- coding: utf-8 -*-
 
 
def merge(right: list, left: list, result: list):
    result.append((left if left[0] < right[0] else right).pop(0))
    return merge(right, left, result) if left and right else result + left + right
 
 
def merge_sort(collection: list):
    if len(collection) == 1:
        return collection
    return merge(merge_sort(collection[len(collection) // 2:]),
                 merge_sort(collection[:len(collection) // 2]), [])
 
 
print(merge_sort([3, 2, 5, 4, 1, 6, 0, 10, 15]))
Добавлено через 18 минут
ncmps, проблема в том, что "не работающим" способом ты создаешь копию списка, а вторым ты пишешь уже в существующий список, твоя функция sort возвращает этот список, но когда ты начинаешь сортировать, обрати внимание на:

Цитата Сообщение от ncmps Посмотреть сообщение
Python
1
2
    sort(left)
    sort(right)

и

Цитата Сообщение от ncmps Посмотреть сообщение
Python
1
return original_list
2
0 / 0 / 0
Регистрация: 14.02.2020
Сообщений: 7
17.03.2020, 15:59  [ТС]
DmFat, спасибо, буду изучать )
Но тема для того и создана в Python для начинающих, что я только учусь и потому использую тот синтаксис, который знаю )

И всё-таки интересно было бы разобраться, почему не работает в моём примере.

Спасибо, попробую осознать. Пока ещё не совсем понял...
0
Модератор
Эксперт Python
 Аватар для Fudthhh
2695 / 1601 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
17.03.2020, 16:13
Лучший ответ Сообщение было отмечено ncmps как решение

Решение

Исправление функции:
Python
1
2
3
4
5
6
7
8
9
10
11
12
def sort(original_list: list):
    if len(original_list) <= 1:
        return original_list
    middle = len(original_list) // 2
    left = original_list[:middle]
    right = original_list[middle:]
    print('left:', left, 'right:', right)
    temp_list = merge(sort(left), sort(right))
    print('temp_list:', temp_list)
    original_list = temp_list.copy()
    print('original_list:', original_list)
    return original_list
Добавлено через 59 секунд
temp_list.copy() вместо этого, ты можешь ставить свои "не работающие" функции.

Добавлено через 13 минут
ncmps, пример твоей ошибки, попытался максимально расписать:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# -*- coding: utf-8 -*-
 
 
def create_list(original: list, iteration: int = 0) -> list:
    if len(original) > 10:                      # Если длина спика достигла 10, то
        return original                         #     Возвращаем список
    temp = original[:]                          # Создаем [КОПИЮ] списка
    temp.append(len(original))                  # Добавляем переменную
    trash = create_list(temp, iteration + 1)    # Вызываем функцию снова, передаем [КОПИЮ] списка и повторяем твою ошибку
    print(iteration, trash)
    return original                             # Вовращаем [ОРИГИНАЛ] списка
 
 
print(create_list([]))
1
0 / 0 / 0
Регистрация: 14.02.2020
Сообщений: 7
17.03.2020, 19:28  [ТС]
Задал вопрос, получил подробный ответ, вроде всё хорошо, но в итоге всё равно ничего не понял ) Видимо ещё не дорос, придётся вернуться позже.
В любом случае спасибо.
0
Эксперт Python
5438 / 3859 / 1215
Регистрация: 28.10.2013
Сообщений: 9,552
Записей в блоге: 1
17.03.2020, 20:50
Лучший ответ Сообщение было отмечено ncmps как решение

Решение

Цитата Сообщение от ncmps Посмотреть сообщение
но в итоге всё равно ничего не понял
Прочитай псевдокод этой сортировки в википедии.
Там все тоже самое, только ты не сделал присваивания
Python
1
2
left = mergesort(left)
right = mergesort(right)
и
Python
1
2
if len(original_list) <= 1:
        return
и ничего не вернул здесь. Нужно возвращать исходный список.

А вот эта штука
Python
1
original_list = list(temp_list[i] for i in range(len(original_list)))
прекрасно работает.
1
0 / 0 / 0
Регистрация: 14.02.2020
Сообщений: 7
19.03.2020, 01:30  [ТС]
Garry Galler, теперь вроде допёр. Спасибо!
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38177 / 21112 / 4307
Регистрация: 12.02.2012
Сообщений: 34,716
Записей в блоге: 14
19.03.2020, 08:40
Вот еще одна реализация сортировки слиянием - совсем элементарная:

Python
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# Слияние двух упорядоченных списков:
 
def merge(s1,s2):
    r=[]
    i,j=0,0
    while(True):
        if i>= len(s1):
            r+=s2[j:]
            break
        if j>= len(s2):
            r+=s1[i:]
            break
        if s1[i] < s2[j]:
            r+=[s1[i]]
            i+=1 
        else:
            r+=[s2[j]]
            j+=1
    return r
 
# собственно сортировка
    
def mergeSort(x):
    xx=[]    # превращаем каждый элемент в список
    for a in x:
        xx=xx+[[a]]
    while(True):
        k=len(xx)  # когда остался единственный список - конец
        if k==1:
            break
        yy=[]
        i=0
        j=1
        while(True): # строим списки пар, потом четверок и т.п.
            if i==k: 
                break
            if j==k:
                yy+=[xx[i]]
                break
            else:
                yy+=[merge(xx[i],xx[j])]
            i+=2
            j+=2
            
        xx=yy
    return xx[0]
 
z=mergeSort([1,2,3,1,2,3,1,2,3])
print(z)
 
z=mergeSort([1,3,-4,8,2,34])
print(z)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.03.2020, 08:40
Помогаю со студенческими работами здесь

Сортировка слиянием
Написать функцию, которая принимает на вход любой массив/список и выдает все промежуточные списки, которые получаются в процедуре MergeSort...

Сортировка слиянием
def merge(l: list, r: list): c = * (len(l) + len(r)) i = k = n = 0 while i &lt; len(l) and k &lt; len(r): if l &lt;= r:...

Сортировка слиянием
Помогите пожалуйста! Нужно написать программу, выполняющую сортировку слиянием с описанием каждой строки, чтобы она выполняла сортировку...

Сортировка слиянием из файла
Нашел на просторах форума данный код и дополнил так, что бы он брал числа из файла def mergeSort(alist): if len(alist)&gt;1: ...

Сортировка слиянием на языке Питон
Помогите пожалуйста. Я никогда не работал с языком питон. помогите написать сортировку слиянием размерность сортируемой последовательности...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

Новые блоги и статьи
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru