Python学习笔记(七)——排序与搜索

心不动则不痛 提交于 2020-01-30 12:37:03

一、排序

1.冒泡排序

def bubbleSort(theSeq):
    for i in range(len(theSeq) - 1):
        for j in range(i + 1, len(theSeq)):
            if theSeq[i] > theSeq[j]:
                theSeq[i], theSeq[j] = theSeq[j], theSeq[i]
    return theSeq

2.选择排序

def selectionSort(theSeq):
    n = len(theSeq)
    for i in range(n - 1):
        smallNdx = i
        for j in range(i + 1, n):
            if theSeq[j] < theSeq[smallNdx]:
                smallNdx = j
            if smallNdx != i:
                theSeq[i], theSeq[smallNdx] = theSeq[smallNdx], theSeq[i]
    return theSeq

3.插入排序

def insertionSort(theSeq):
    n = len(theSeq)
    for i in range(1, n):
        value = theSeq[i]
        pos = i
        while pos > 0 and value < theSeq[pos - 1]:
            theSeq[pos] = theSeq[pos - 1]
            pos -= 1
        theSeq[pos] = value
    return theSeq

 4、合并排序

(1)

def MergeSort(theList):
    if len(theList) <= 1:
        return theList
    else:
        mid = len(theList) // 2
    
        leftHalf = MergeSort(theList[:mid])
        rightHalf = MergeSort(theList[mid:])

        newList = mergeSortedLists(leftHalf, rightHalf)
        return newList

def mergeSortedLists(listA, listB):
    newList = list()
    a = 0
    b = 0

    while a < len(listA) and b < len(listB):
        if listA[a] < listB[b]:
            newList.append(listA[a])
            a += 1
        else:
            newList.append(listB[b])
            b += 1
    while a < len(listA):
        newList.append(listA[a])
        a += 1
    while b < len(listB):
        newList.append(listB[b])
        b += 1
    return newList

(2)

def MergeSort(theSeq):
    n = len(theSeq)
    tmpArray = Array(n)
    recMergeSort(theSeq, 0, n-1, tmpArray)

def recMergeSort(theSeq, first, last, tmpArray):
    # Check the base case: the virtual sequence contains a single item.
    if first == last:
        return 
    else:
        mid = (first + last) // 2
        
        # Split the sequence and perform the recursive step.
        recMergeSort(theSeq, first, mid, tmpArray)
        recMergeSort(theSeq, mid+1, last, tmpArray)

        # Merge the two ordered subsequences.
        mergeVirtualSeq(theSeq, first, mid+1, last+1, tmpArray)
    

def mergeVirtualSeq(theSeq, left, right, end, tmpArray):
    # Merges the two sorted virtual subsequences: [left..right) [right..end) 
    # using the tmpArray for intermediate storage. 
    a = left
    b = right
    # Initialize an index variable for the resulting merged array.
    m = 0

    # Merge the two sequences together until one is empty.
    while a < right and b < end:
        if theSeq[a] < theSeq[b]:
            tmpArray[m] = theSeq[a]
            a += 1
        else:
            tmpArray[m] = theSeq[b]
            b += 1
        m += 1

    while a < right:
        tmpArray[m] = theSeq[a]
        a += 1
        m += 1
    
    while b < end:
        tmpArray[m] = theSeq[b]
        b += 1
        m += 1
    
    # Copy the sorted subsequence back into the original sequence structure.
    for i in range(end - left):
        theSeq[i+left] = tmpArray[i]

5、快速排序

(1)

def quickSort(theSeq):
    n = len(theSeq)
    recQuickSort(theSeq, 0, n-1)

def recQuickSort(theSeq, first, last):
    if first >= last:
        return
    else:
        pivot = theSeq[first]
        pos = partitionSeq(theSeq, first, last)
        recQuickSort(theSeq, first, pos - 1)
        recQuickSort(theSeq, pos + 1, last)

def partitionSeq(theSeq, first, last):
    pivot = theSeq[first]
    left = first + 1
    right = last
    while left <= right:
        while left < right and theSeq[left] < pivot:
            left += 1
        while right >= left and theSeq[right] >= pivot:
            right -= 1
    
        if left < right:
            theSeq[left], theSeq[right] = theSeq[right], theSeq[left]
    if right != first:
        theSeq[first] = theSeq[right]
        theSeq[right] = pivot
    
    return right

 (2)

# Sorts a sequence of positive integers using the radix sort algorithm.
from llistqueue import Queue
from array import Array 

def radixSort(intList, numDigits):
    # Create an array of queues to represent the bins. 
    binArray = Array(10)
    for k in range(10):
        binArray[k] = Queue()
    column = 1
    for _ in range(numDigits):
        for key in intList:
            digit = (key // column) % 10
            binArray[digit].enqueue(key)
        i = 0
        for bin in binArray:
            while not bin.isEmpty():
                intList[i] = bin.dequene()
                i += 1
        
        column *= 10

6.给链表排序

(1)插入排序

class ListNode:
    def __init__(self, data):
        self.data = data
        self.next = None


def llistInsertionSort(origList):
    # Make sure the list contains at least one node. 
    if origList is None:
        return None
    
    # Iterate through the original list. 
    newList = None
    while origList is not None:
        # Assign a temp reference to the first node. 
        curNode = origList

        # Advance the original list reference to the next node. 
        origList = origList.next
        
        # Unlink the first node and insert into the new ordered list. 
        curNode.next = None
        newList = addToSortedList(newList, curNode.data)
    # Return the list reference of the new ordered list.
    return newList


# 这个其实就是链表那一节的insert()函数
def addToSortedList(head, value):
    predNode = None
    curNode = head
    while curNode is not None and value > curNode.data:
        predNode = curNode
        curNode = curNode.next
    newNode = ListNode(value)
    newNode.next = curNode

    if curNode is head:
        head = newNode
    else:
        predNode.next = newNode

    return head

(2)合并排序

def llistMergeSort(theList):
    if theList is None:
        return None
    
    elif theList.next == None:
        return theList
    # Split the linked list into two sublists of equal size. 
    else:
        rightList = _splitLinkedList(theList)
        leftList = theList

        
        leftList = llistMergeSort(leftList)
        rightList = llistMergeSort(rightList)
        
        # Merge the two ordered sublists.
        theList = _mergeLinkedLists(leftList, rightList)
        
        # Return the head pointer of the ordered sublist.
        return theList


# Splits a linked list at the midpoint to create two sublists. 
# The head reference of the right sublist is returned. 
# The left sublist is still referenced by the original head reference.
def _splitLinkedList(subList):
    # Assign a reference to the first and second nodes in the list.
    midPoint = subList
    curNode = midPoint.next
    # Iterate through the list until curNode falls off the end. 
    while curNode is not None:
        curNode = curNode.next

        if curNode is not None:
            midPoint = midPoint.next
            curNode = curNode.next
    
    # Set rightList as the head pointer to the right sublist. 
    rightList = midPoint.next
    # Unlink the right sub list from the left sublist.
    midPoint.next = None
    return rightList

def _mergeLinkedLists(subListA, subListB):
    # Create a dummy node and insert it at the front of the list. 
    newList = ListNode(None)
    newTail = newList

    # Append nodes to the new list until one list is empty.
    while subListA is not None and subListB is not None:
        if subListA.data <= subListB.data:
            newTail.next = subListA
            subListA = subListA.next
        else:
            newTail.next = subListB
            subListB = subListB.next
        
        newTail = newTail.next
        newTail.next = None
    
    # If self list contains more terms, append them.
    if subListA is not None:
        newTail.next = subListA
    else:
        newTail.next = subListB
    # Return the new merged list, which begins with the first node after the dummy node.
    return newList.next

 

二、搜索

1.二分法搜索

def binarySearch(theValues, target):
    low = 0
    high = len(theValues) - 1
    while low <= high:
        mid = (high + low) // 2
        # Does the midpoint contain the target? 
        if theValues[mid] == target:
            return True
        # Or does the target precede the midpoint? 
        elif target < theValues[mid]:
            high = mid - 1
        # Or does it follow the midpoint?
        else:
            low = mid + 1
    # If the sequence cannot be subdivided further, we're done.
    return False

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!