算法导论 python代码 第二章

来源:互联网 发布:设计触点矩阵 编辑:程序博客网 时间:2024/05/16 09:44
<pre name="code" class="python"># author Ttssxuan# this is the sample of the selection sortdef selection_sort(arr):    '''selection sort.       arr: the arr you want to sort'''    # find the ith element of the arr    for i in range(0, len(arr) - 1):        min = i        # find the min element in rest        for j in range(i + 1, len(arr)):            if arr[j] < arr[min]:                min = j        #swap the ith element to the ith position        temp = arr[min]        arr[min] = arr[i]        arr[i] = temp#testarr = [2, 4, 5, 9, 4]selection_sort(arr)print(str(arr))


# author Ttssxuan# Insertion sort, sort the arr with ascent orderdef insertion_sort(arr):    '''Insertion_sort, arr: the input arr that we want to sort'''    # scan every element of the arr and find the properly place for it    for j in range(1, len(arr)):        key = arr[j]        i = j - 1        # scan the sorted subarray arr[0..j -1], find the proper place        while(i >= 0 and key < arr[i]):            arr[i + 1] = arr[i]            i = i - 1        arr[i + 1] = key# testarr = [6, 2, 3, 4, 5]insertion_sort(arr)print(str(arr))


# author Ttssxuan# Chapter 2# merge sort, the provide two kinds of method to merge the two sequece.from math import floordef Merge(arr, p, q, e):    '''The merge, arr:the array need to merge, p:the start place of the first    part, q:the end of the first part, e:the end of the sencond merge part.    This is the version of with sentinel.'''    n1 = q - p + 1    n2 = e - q    l = [0] * (n1 + 1)    r = [0] * (n2 + 1)    # copy the first part from the initial arr    for i in range(0, n1):        l[i] = arr[p + i]    # copy the second part from the initial arr    for j in range(0, n2):        r[j] = arr[q + j + 1]    # set the sentinel of the two part    l[n1] = 10000    r[n2] = 10000    i = 0    j = 0    # merge the two part to arr    for k in range(p, e):        if l[i] <= r[j]:            arr[k] = l[i]            i += 1        else:            arr[k] = r[j]            j += 1def Merge_no_sentinel(arr, p, q, e):    '''The merge, arr:the array need to merge, p:the start place of the first    part, q:the end of the first part, e:the end of the sencond merge part.    This is the version of without sentinel'''    n1 = q - p + 1    n2 = e - q    l = [0] * n1    r = [0] * n2    # copy the first part from the initail arr    for i in range(0, n1):        l[i] = arr[p + i]    # copy the second pary from the initail arr    for j in range(0, n2):        r[j] = arr[q + j + 1]            i = 0    j = 0    # merge the two part until one of the two part encount the end    for k in range(p, e + 1):        if (i < n1 and j < n2):            if l[i] <= r[j]:                arr[k] = l[i]                i += 1            else:                arr[k] = r[j]                j += 1        else:            break    # copy the rest of the two part to the initail arr    if i < n1:        while k <= e:            arr[k] = l[i]            k += 1            i += 1    if j < n2:        while k <= e:            arr[k] = r[j]            k += 1            j += 1def Merge_sort(arr, s, e):    '''Use merge sort algorithm to sort the arr, and the start position is s,    the end position is e.'''    if s != e:        # get the middle of the arr for s to e        mid = int(floor((s + e) / 2))        # merge sort the first part        Merge_sort(arr, s, mid)        # merge sort the second part        Merge_sort(arr, mid + 1, e)        # merge the tow part        Merge_no_sentinel(arr, s, mid, e)#testarr = [1, 3, 5, 2, 4, 6]Merge_sort(arr, 0, len(arr) - 1)print(str(arr))

# author Ttssxuan# 2.3-5# binary searchimport mathdef binary_search(arr, value, s, e):    '''arr:input, value:the value you wanted, s: start place in the arr, e:the    end place in the arr    if no such value RETURN -1, else RETURN the place of the value'''    if s > e:        return -1    else:        # get the middle of the index        mid = int(math.floor((s + e) / 2))        # judge the mid is equal the value        if arr[mid] == value:            return mid        # search the first half        elif arr[mid] > value:            return binary_search(arr, value, s, mid - 1)        # search the second half        else:            return binary_search(arr, value, mid + 1, e)# testarr = [1, 2, 3, 4, 5]place = binary_search(arr, 1, 0, len(arr) - 1)if place != -1:    print("the place is ", place)else:    print("no such value")


# author Ttssxuan# 2.3-7# Describe a ‚.n lg n/-time algorithm that, given a set S of n integers# and another integer x, determines whether or not there exist two# elements in S whose sum is exactly x.from math import floorimport mathdef Merge_no_sentinel(arr, p, q, e):    '''The merge, arr:the array need to merge, p:the start place of the first    part, q:the end of the first part, e:the end of the sencond merge part.    This is the version of without sentinel'''    n1 = q - p + 1    n2 = e - q    l = [0] * n1    r = [0] * n2    # copy the first part from the initail arr    for i in range(0, n1):        l[i] = arr[p + i]    # copy the second pary from the initail arr    for j in range(0, n2):        r[j] = arr[q + j + 1]            i = 0    j = 0    # merge the two part until one of the two part encount the end    for k in range(p, e + 1):        if (i < n1 and j < n2):            if l[i] <= r[j]:                arr[k] = l[i]                i += 1            else:                arr[k] = r[j]                j += 1        else:            break    # copy the rest of the two part to the initail arr    if i < n1:        while k <= e:            arr[k] = l[i]            k += 1            i += 1    if j < n2:        while k <= e:            arr[k] = r[j]            k += 1            j += 1def Merge_sort(arr, s, e):    '''Use merge sort algorithm to sort the arr, and the start position is s,    the end position is e.'''    if s != e:        # get the middle of the arr for s to e        mid = int(math.floor((s + e) / 2))        # merge sort the first part        Merge_sort(arr, s, mid)        # merge sort the second part        Merge_sort(arr, mid + 1, e)        # merge the tow part        Merge_no_sentinel(arr, s, mid, e)def binary_search(arr, value, s, e):    '''arr:input, value:the value you wanted, s: start place in the arr, e:the    end place in the arr    if no such value RETURN -1, else RETURN the place of the value'''    if s > e:        return -1    else:        mid = int(math.floor((s + e) / 2))        if arr[mid] == value:            return mid        elif arr[mid] > value:            return binary_search(arr, value, s, mid - 1)        else:            return binary_search(arr, value, mid + 1, e)def estimate(arr, value):    '''arr: the set which you want to search, value: the value you want to        search.        Return [first, second], if get the place, the first and second present        the place of the two value, else return [-1, -1]'''    # sort the array first    Merge_sort(arr, 0, len(arr) - 1)    # search each element of the arr    for first in range(0, len(arr)):        # calculate the other of the two        rest = value - arr[first]        # use binary search verify if there is the value        second = binary_search(arr, rest, first + 1, len(arr) - 1)                if second != -1:            return [first, second]    return [-1, -1]# test arr = [1, 3, 4, 5]print(arr)result = estimate(arr, 10)print(result)result = estimate(arr, 4)print(result)result = estimate(arr, -1)print(result)

# author Ttssxuan# Problem 2-2# bubblesortdef bubble_sort(arr):    # total rearrange len(arr) times    for i in range(0, len(arr) - 1):        # swap the min of the arr[i, len(arr) - 1] to the top        for j in range(len(arr) - 1, i, -1):            if arr[j] < arr[j - 1]:                # swap arr[j], arr[j - 1]                arr[j], arr[j - 1] = arr[j - 1], arr[j]# testarr = [9, 2, 5, 2, 0, 2]bubble_sort(arr)print(arr)

# author Ttssxuan# Problem 2-4 d# Give an algorithm that determines the number of inversions in any permutation# on n elements in ‚.n lg n/ worst-case time.# We implement it by modifying merge sortfrom math import floordef Merge_no_sentinel(arr, p, q, e):    '''The merge, arr:the array need to merge, p:the start place of the first    part, q:the end of the first part, e:the end of the sencond merge part.    This is the version of without sentinel    return the inversion number of this merge'''    n1 = q - p + 1    n2 = e - q    l = [0] * n1    r = [0] * n2        # copy the first part from the initail arr    for i in range(0, n1):        l[i] = arr[p + i]    # copy the second pary from the initail arr    for j in range(0, n2):        r[j] = arr[q + j + 1]    # recorder the total number of inversion    inversion_number = 0    # recorder the number of the numbers in array "r" which was added in "arr"    count = 0    i = 0    j = 0    # Merge the two part until one of the two part encount the end.    # We know that if the number in ther array "l" less than the number in the    # array "r", the pair of the number is not inversion, so we just count the    # number in array "r" which added in the "arr" before the number in array    # "l". Each this occur, we know there is inversion.     for k in range(p, e + 1):        if (i < n1 and j < n2):            if l[i] <= r[j]:                arr[k] = l[i]                i += 1                # add the inversion for this number                inversion_number += count            else:                arr[k] = r[j]                j += 1                # increase the number which was added in "arr"                count += 1        else:            break    # copy the rest of the two part to the initail arr    if j < n2:        while k <= e:            arr[k] = r[j]            k += 1            j += 1    if i < n1:        while k <= e:            arr[k] = l[i]            k += 1            i += 1            # add the inversion for this number            inversion_number += count    return inversion_number    def Merge_sort(arr, s, e):    '''Use merge sort algorithm to sort the arr, and the start position is s,    the end position is e.    return the inversion number of the arr'''    inversion_number = 0    if s != e:        # get the middle of the arr for s to e        mid = int(floor((s + e) / 2))        # merge sort the first part        inversion_number += Merge_sort(arr, s, mid)        # merge sort the second part        inversion_number += Merge_sort(arr, mid + 1, e)        # merge the tow part        inversion_number += Merge_no_sentinel(arr, s, mid, e)    return inversion_numberdef count_inversion(arr):    '''count the inversion number of a sequence, which was implement by change    the merge sort    arr: the sequence we want to count    return the inversion number of the sequence.'''    return Merge_sort(arr, 0, len(arr) - 1)#testarr = [1, 2, 0, -1]re = count_inversion(arr)print rearr = [0, 1, 2, 3]re = count_inversion(arr)print rearr = [5, 4, 3, 2, 1]re = count_inversion(arr)print re


0 0
原创粉丝点击