Подтвердить что ты не робот

Как работает сортировка вставки Python?

Здесь реализация сортировки вставки на Python, я попытался выполнить значения на бумаге, но как только переменная подсчета я становится больше, чем len (s), я не знаю, что делать, как/почему она все еще работает?

def sort_numbers(s):
    for i in range(1, len(s)):
        val = s[i]
        j = i - 1
        while (j >= 0) and (s[j] > val):
            s[j+1] = s[j]
            j = j - 1
        s[j+1] = val

def main():
    x = eval(input("Enter numbers to be sorted: "))
    x = list(x)
    sort_numbers(x)
    print(x)
4b9b3361

Ответ 1

Или это:

def ins_sort(k):
    for i in range(1,len(k)):    #since we want to swap an item with previous one, we start from 1
        j = i                    #bcoz reducing i directly will mess our for loop, so we reduce its copy j instead
        temp = k[j]              #temp will be used for comparison with previous items, and sent to the place it belongs
        while j > 0 and temp < k[j-1]: #j>0 bcoz no point going till k[0] since there is no seat available on its left, for temp
            k[j] = k[j-1] #Move the bigger item 1 step right to make room for temp
            j=j-1 #take k[j] all the way left to the place where it has a smaller/no value to its left.
        k[j] = temp
    return k

Ответ 2

Рассмотрим [3, 2, 1]

Цикл начинается с 3. Поскольку это первый элемент в списке, нечего делать.

[3, 2, 1]

Следующий элемент - 2. Он сравнивает от 2 до 3 и, поскольку 2 меньше 3, он меняет их, сначала помещая 3 во второе положение, а затем помещая 2 в первую позицию.

[2, 3, 1]

Последний элемент равен 1. Так как 1 меньше 3, он перемещается на 3.

[2, 3, 3]

Так как 1 меньше 2, то свопы перемещаются на 2.

[2, 2, 3]

Затем он вставляет 1 в начале.

[1, 2, 3]

Ответ 3

Чтобы увидеть, как работает эта реализация, просмотрите ее здесь: http://goo.gl/piDCnm

Однако здесь менее сложная реализация сортировки вставки:

def insertion_sort(seq):
    for i in range(1, len(seq)):
        j = i
        while j > 0 and seq[j - 1] > seq[j]:
            seq[j - 1], seq[j] = seq[j], seq[j - 1]
            j -= 1

Ответ 4

рекурсивная реализация

def insert(x, L):
    if [] == L:      return [x]
    elif x <= L[0]:  return [x] + L
    else:            return [L[0]] + insert(x,L[1:])

def insertion_sort(L):
    if [] == L:  return []
    else:        return insert(L[0], insertion_sort(L[1:]))

# test
import random

L = [random.randint(1,50) for _ in range(10)]

print L
print insertion_sort(L)

Ответ 5

Если мы рассмотрим массив слева направо [LeftMost,..., RightMost], сортировка вставки выполняет следующую процедуру для каждого элемента:

  • Получить текущее значение i.
  • Получить значение j (где j = i-1 в первой итерации или в основном первый элемент слева от i). В первой итерации массива while [i] и array [j] находятся последовательные элементы. Например, если array = [... 60, 100, 50,...] и array [i] равно 50, тогда массив [j] равен 100.
  • Если предыдущее значение больше текущего, то оно меняет местами два значения. В основном, если у вас есть что-то вроде [..., 60, 100, 50,...] до этой операции, вы получите [..., 60, 50, 100,...]. Идея состоит в том, что вы перемещаете каждый элемент, который я оставил, пока есть элементы слева от него, которые ниже.

    Это ключ алгоритма сортировки. После того, как вы закончите обработку в элементе i, у вас есть отсортированный массив, из которого он первоначально был полностью в начале (осталось больше всего).

  • Уменьшите значение j на единицу. и вернемся к шагу 1 (В этом примере это приведет к тому, что вы сравните 50 и 60 и замените их).
Если вы внимательно посмотрите на код, вы никогда не получите точку, где я >= len (s) (range является функцией который создает список, а значение я не изменяется внутри цикла). Вы можете представить переменную я как воображаемую стрелку, указывая на позицию в массиве, которая имеет все отсортированные элементы слева от нее. Переменная j просто перемещается влево с фиксированным i, чтобы поменять исходное значение массива [i], пока не найдет другое значение, равное или меньшее, чем оно.

Sidenote (не важно понимать алгоритм, но может быть полезно): имея в виду, вы можете сделать вывод, что эта сложность алгоритма (измеренная в худшем случае сравнения) равна O (N ^ 2), где N = len (s). Это похоже на наличие двух вложенных операторов.

Это видео отлично справляется с этим, и вы знаете, что говорят, изображение стоит 1000 слов.

Ответ 6

Есть несколько кусочков информации, которые помогут разобраться в сортировке вставок.

Прежде всего, i никогда не становлюсь больше, чем len(s). На самом деле, это никогда не равно ему. range(1, len(s)) создает неизменяемую последовательность, по которой вы можете выполнять итерации. Что вы будете иметь под следующим утверждением (предположим, что len(s) = 3):

for i in range(1, len(s)):
    ...

это что-то вроде этого:

for i in (1, 2):
    ...

Вы можете убедиться в этом сами:

>>> list(range(1, 3))
>>> [1, 2]

Таким образом, вы будете повторять два раза, первый раз с i = 1, а второй раз с i = 2.

Во-вторых, это помогает напомнить себе, что сортируемый вами список состоит, по сути, из двух частей: сортируемой части (list[0:i-1]) и части, которая еще не отсортирована ([list[i:]). То, чего вы пытаетесь достичь с помощью вставки сортировки на каждой итерации, - это найти место для помещения текущего значения в отсортированный список. Мы вернемся к этому в ближайшее время.

В-третьих, алгоритм можно рассматривать как выполняющий две совершенно разные задачи. Первый - перебрать все элементы в списке и убедиться, что список отсортирован. То, чем занимается этот внешний цикл (конечно, внутренний цикл участвует в реальных проверках, но это помогает сделать это упрощение). Другой - найти подходящие позиции для элементов в списке, чтобы список был отсортирован. То есть, если у вас есть список letters = ['a', 'b', 'd', 'c'], 'c' очевидно, должен идти на letters[2] а 'd' должен занимать 'c' прежнее место если список должен быть отсортирован в порядке возрастания. То есть та часть, которая внутренние в while цикл делает.

То, как цикл while (и оператор s[j+1] = val) гарантирует, что список отсортирован, на самом деле довольно умно. Во-первых, он гарантирует, что мы не перегружены (условие j >= 0). То есть мы не s[-1] элемент s[-1], который в Python будет последним элементом в списке, и другие языки, такие как Java, исключение ArrayIndexOutOfBounds. Затем он спрашивает: номер, который я держу, ниже, чем предыдущий? Если это так, это означает, что список не отсортирован, и нам нужно переместить большее число на одну позицию ближе к концу списка (если хотите, вправо). Обратите внимание, что элемент, с которым мы сравниваем другие элементы, остается тем же. Мы держим его в переменной val. Поэтому нам не нужно беспокоиться о случайной потере, перезаписывая его при перемещении значений.

Теперь, когда мы переместим большее значение вправо, мы уменьшим j и снова зададим тот же вопрос: больше ли значение в s[j] чем то, которое мы имеем в val? Мы продолжаем делать это до тех пор, пока не найдем значение, которое ниже, чем у нас в val, или пока не достигнем s[0] не найдя более низкого значения. Это означает, что то, что у нас есть, является самым низким номером в списке. В любом случае, мы нарушаем из в while циклы и перезапись s[j+1] со значением, которое мы имеем, так что мы не обесцениваться val.

Чтобы увидеть, как это выглядит на практике, рассмотрим список: [2, 3, 4, 5, 1]. Допустим, мы повторяем, пока не достигнем числа 1, и в этот момент мы входим в цикл while, поскольку 5 > 1. Предпринятые шаги будут:

2, 3, 4, 5, 1   # val = 1, s[j] = 5, j = 3       5 > 1
2, 3, 4, 5, 5   # val = 1, s[j] = 4, j = 2       4 > 1
2, 3, 4, 4, 5   # val = 1, s[j] = 5, j = 1       3 > 1
2, 3, 3, 4, 5   # val = 1, s[j] = 5, j = 0       2 > 1
2, 2, 3, 4, 5   # val = 1, s[j] = 5, j = -1      break out of while
1, 2, 3, 4, 5   # val = 1, s[j] = 5, j = -1      put val into s[0]

И это в основном это. Выполните итерацию по циклу, убедитесь, что значения перед текущим меньше, чем то, которое мы храним, и, если нет, переместите эти значения вправо, чтобы освободить место для нашего значения. И вот оно у вас есть - сортировка вставок.

Изменение: есть очень хорошее, наглядное объяснение при просмотре кода, если вам все еще трудно понять, как он работает.

Ответ 7

def insertionsort(list):
    for i in range(1,len(list)):
        temp=list[i]
        j=i-1
        while temp<+list[j] and j>=0:
            list[j+1]=list[j]
            j=j-1
        list[j+1]=temp
    return list
list=eval(raw_input('Enter a list:'))
print insertionsort(list)

Это поможет вам.

Ответ 8

Функция python range(start, end) начинает отсчет от start до end - 1. То есть, end никогда не будет частью значений range(). Итак, если у вас есть, например, range(len(A)), а A - массив (в Python, список) из 10 целых чисел, len(A) будет 10, а range(len(A)) вернет (0,1,2,3,4,5,6,7,8,9), чтобы вы могли индексировать каждый элемент в A.

В вашем случае я никогда не становлюсь больше len(s) - 1.

После вашего кода на бумаге может быть полезно, но вы должны убедиться, что язык программирования делает именно то, что вы думаете, что он делает, а иногда реализация не интуитивно понятна. Быстрый и простой способ отслеживания ваших значений программы - использовать операторы print. Например:

def sort_numbers(s):
    for i in range(1, len(s)):

        # let see what values i takes on
        print "i = ", i

        val = s[i]
        j = i - 1
        while (j >= 0) and (s[j] > val):
            s[j+1] = s[j]
            j = j - 1
        s[j+1] = val

Ответ 9

def insertionSort(alist):
    for index in range(1, len(alist)):

        currentvalue = alist[index]
        position = index

        while position > 0 and alist[position-1] > currentvalue:
            alist[position] = alist[position-1]
            print(alist)
            position -= 1

        alist[position] = currentvalue

alist = [int(i) for i in input().split()]       
insertionSort(alist)

Ответ 10

__author__ = 'Dharmjit'  
def InsertionSort(list):  
    for index in range(1,len(list)):  
        curr = list[index]  
        position = index  

        while position > 0 and list[position-1] > curr:  
            list[position] = list[position-1]  
            position = position - 1  

        list[position] = curr  
    return list  

l = [2,1,5,3,9,6,7]  
print(InsertionSort(l))  
[1,2,3,5,6,7,9]  

Вы можете увидеть всю концепцию здесь - http://pythonplanet.blogspot.in/2015/07/sorting-algorithm-1-insertion-sort.html

Ответ 11

def insertion(x):
    for i in range(1, len(x)):
        while x[i - 1] > x[i] and i >= 0:
            x[i - 1], x[i] = x[i], x[i - 1]
            i -= 1
    return x

Что-то вроде этого

Ответ 12

Простая комбинация сортировки списка и сортировки пузырьков

s = [54,26,93,17,77,31,44,55,20]

for i in range(1,len(s)+1):
    b = s[0:i]
    a = b
    count = 0

    while count<len(a):                  # while loop to perform the for loop len(a) number of times-like in bubble sort
        for j in range(len(a)-1):        # for loop compares every j'th element with next element
            if a[j] >= a[j+1-len(a)]:
                temp = a[j]
                a[j] = a[j+1-len(a)]
                a[j+1-len(a)] = temp

        count = count+1
print a    

Ответ 13

+ Альтернатива с двумя для петель и описательных имен.

def insertionSort(list):
  for outerIndex in range(len(list)):
    for innerIndex in range(outerIndex, 0, -1):
      if list[innerIndex] >= list[innerIndex - 1]:
        break
      list[innerIndex], list[innerIndex - 1] = list[innerIndex - 1], list[innerIndex]
  return list

print insertionSort([3, 1e-10, 7e5, 2.3, 100, -2.5, 12.1])
# => [-2.5, 1e-10, 2.3, 3, 12.1, 100, 700000.0]

Ответ 14

Вставка Сортировка через рекурсию:

k=1# def insertionsort(a): # should be written before k=1
c=a[:]
def swap(k,c,a):
    if c[k-1] > c[k]:
        c[k-1] = a[k]
        c[k] = a[k-1]
        a = c[:]
        if max(c[:k])!= c[k-1]:
            swap(k-1,c,a)
    if k < len(a)-1:
       return swap(k + 1, c,a)
    return c
return swap(k,c,a)

print(insertionsort(b))

Ответ 15

Простой способ сортировки массива.

# Mutate the constant input 
# loop into the array
# check if the array[j] have to be greater than 0 and a[j] is less than a[j - 1] 
# then swap values and decrease the value swapped.

def insertionSort(array):
  a = array
  for i in range(0,len(a)):
    j = i
    while j > 0 and a[j] < a[j - 1]:
      a[j], a[j - 1] = a[j - 1], a[j]
      j -= 1
  return a

# input-> [2,1,3] then array[j] > 0 and array[j] < array[j - 1] -> swap -> decrease j

Ответ 16

Попробуйте это, работает как для увеличения, так и для уменьшения порядка:

import operator

def insertion_sort(arr, reverse=False):
    # check if array is empty or not
    if arr is None:
        raise TypeError("Data cannot be none")

    n = len(arr)
    # if length of array is less than two it is already sorted
    if n < 2:
        return arr

    lgt = operator.gt if reverse else operator.lt

    # Traverse through 1 to len(arr)
    for i in range(1, n):
        key = arr[i]
        j = i-1
        while j >= 0 and lgt(key, arr[j]):
            arr[j+1] = arr[j]
            j -= 1
        arr[j+1] = key
    return arr

li = [1, 4, 8, 9, 42, 0, 36]
print(insertion_sort(li))

Ответ 17

def ins(l):
    for i in range(1, len(l)):
        current_index = i
        current_value = l[i]
        while current_index > 0 and current_value < l[current_index - 1]:
            l[current_index] = l[current_index - 1]
            current_index -= 1
        l[current_index] = current_value
    print(l)

Ответ 18

def insertSort(list):
  for i in range(0, len(list)):
    index = list[i] // index holder for swapAt position
    while i > 0 and index < list[i - 1]:
      list[i] = list[i - 1]
      i = i - 1
      list[i] = index
  return list

print(insert([3,3,6,1,7,2,8])) -> [1, 2, 3, 3, 6, 7, 8]

Ответ 19

def sort_numbers(list):
    for i in range(1, len(list)):
        val = list[i]
        j = i - 1
        while (j >= 0) and (list[j] > val):
            list[j+1] = list[j]
            j = j - 1
        list[j+1] = val

n = int(input("Enter the no. of elements"))
list = []
for i in range(0,n):
  t = int(input())
  list.append(t)

sort_numbers(list)

print list

Ответ 20

Я просмотрел ряд этих сообщений, и я думаю, что люди слишком усложняют эту проблему. пожалуйста, исправьте меня, если я сделал это неправильно, но это моя интерпретация такого рода.

def insert(L): # this creates the definition and assines the list that you input to L
    for i in range(len(L)): # this then loops the next code for the length of the list
        while i > 0 and L[i] < L[i-1]: # this is the main part of the code where it checks
        # if the value from the list is less than the one before it and if it is then it 
        # swaps them around 
            L[i-1], L[i] = L[i], L[i-1] # this code just swaps round the values
            print (L)# prints the list out at the end of each part



L = [5,2,3,7,6,9,7]
insert(L)

Используя это, он выдает:

[2, 5, 3, 7, 6, 9, 7]
[2, 3, 5, 7, 6, 9, 7]
[2, 3, 5, 6, 7, 9, 7]
[2, 3, 5, 6, 7, 7, 9]

Функция печати также может быть удалена из строки и может быть помещена вне цикла for, чтобы она только печатала список в конце. Который дал бы только последнюю строку:

[2, 3, 5, 6, 7, 7, 9]

Ответ 21

    def insertie(x):
    nrc=0
    nrm=0
    for i in range(0,len(x)):
        aux=x[i]
        nrm=nrm+1
        j=i-1
        while j >= 0 and aux < x[j]:
            nrc=nrc+1
            x[j+1]=x[j]
            nrm=nrm+1
            j=j-1
        nrc=nrc+1
        x[j+1]=aux
        nrm=nrm+1
    return x

x=[7,5,4,9,1,4,0,1]
print insertie(x)