【数据结构与算法——python】排序与查找

查找

顺序查找—— O ( n ) O(n) O(n)

无序表查找

def sequentialSearch(alist, item):
    pos = 0
    found = False
    while pos < len(alist) and not found:
        if alist[pos] == item:
            found = True
        else:
            pos += 1
    return found
CaseBest CaseWorst CaseAverage Case
item is present 1 1 1 n n n n / 2 n/2 n/2
item is not present n n n n n n n n n

有序表查找

# 有序表查找:
#   当数字大于目标数字时,说明列表中没有所要查找的数字
def orderedSequentialSearch(alist, item):
    pos = 0
    found = False
    stop = False
    while pos < len(alist) and not found and not stop:
        if alist[pos] == item:
            found = True
        else:
            if alist[pos] > item:
                stop = True
            else:
                pos += 1
    return found
CaseBest CaseWorst CaseAverage Case
item is present 1 1 1 n n n n / 2 n/2 n/2
item is not present 1 1 1 n n n n / 2 n/2 n/2

二分查找—— O ( l o g   n ) O(log\ n) O(log n)

二分查找

# 从列表中间开始比对:
#   1.如果列表中间项匹配,则查找结束
#   2.如果不匹配:
#       (1)中间项比查找项大:查找项出现在前半部分
#       (2)中间项比查找项小:查找项出现在后半部分
# 每次范围缩小一半

def binarySearch(alist, item):
    first = 0
    last = len(alist) - 1
    found = False

    while first < last and not found:
        midpoint = (first + last) // 2
        if alist[midpoint] == item:
            found = True
        else:
            if item < alist[midpoint]:
                last = midpoint - 1
            else:
                first = midpoint + 1
    return found

二分查找递归

def binarySearch2(alist, item):
    if len(alist) == 0:
        return False
    else:
        midpoint = len(alist) // 2
        if alist[midpoint] == item:
            return True
        else:
            if item < alist[midpoint]:
                return binarySearch2(alist[:midpoint], item)
            else:
                return binarySearch2(alist[midpoint + 1:], item)

排序

冒泡排序—— O ( n 2 ) O(n^2) O(n2)

冒泡排序

def bubbleSort(alist):
    for passnum in range(len(alist) - 1, 0, -1):
        for i in range(passnum):
            if alist[i] > alist[i + 1]:
                alist[i], alist[i + 1] = alist[i + 1], alist[i]

冒泡排序:性能改进

def shortBubbleSort(alist):
    exchanges = True
    passnum = len(alist) - 1
    while passnum > 0 and exchanges:
        exchanges = False
        for i in range(passnum):
            if alist[i] > alist[i + 1]:
                exchanges = True
                alist[i], alist[i + 1] = alist[i + 1], alist[i]
        passnum -= 1

插入排序—— O ( n 2 ) O(n^2) O(n2)

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]
            position = position - 1
        # 插入新项
        alist[position] = currentValue

谢尔排序—— O ( n 3 2 ) O(n^\frac{3}{2}) O(n23)

def shellSort(alist):
    # 确定间隔
    sublistcount = len(alist) // 2
    while sublistcount > 0:
        # 对子列表进行排序
        for startposition in range(sublistcount):
            gapInsertionSort(alist, startposition, sublistcount)

        print("After increments of size", sublistcount, "The list is", alist)

        # 缩小间隔
        sublistcount = sublistcount // 2


def gapInsertionSort(alist, start, gap):
    for i in range(start + gap, len(alist), gap):
        currentvalue = alist[i]
        position = i
        while position >= gap and alist[position - gap] > currentvalue:
            alist[position] = alist[position - gap]
            position = position - gap
        alist[position] = currentvalue

归并排序—— O ( n l o g   n ) O(nlog\ n) O(nlog n)

def mergeSort(alist):
    if len(alist) > 1:
        mid = len(alist) // 2
        lefthalf = alist[:mid]
        righthalf = alist[mid:]

        # 递归调用
        mergeSort(lefthalf)
        mergeSort(righthalf)

        i = j = k = 0
        while i < len(lefthalf) and j < len(righthalf):
            if lefthalf[i] < righthalf[j]:
                alist[k] = lefthalf[i]
                i += 1
            else:
                alist[k] = righthalf[j]
                j = j + 1
            k += 1
        # 归并左边剩余
        while i < len(lefthalf):
            alist[k] = lefthalf[i]
            i += 1
            k += 1
        # 归并右边剩余
        while j < len(righthalf):
            alist[k] = righthalf[j]
            j += 1
            k += 1
def merge_sort(lst):
    if len(lst) <= 1:
        return lst
    middle = len(lst) // 2
    left = merge_sort(lst[:middle])
    right = merge_sort(lst[middle:])

    merged = []
    while left and right:
        if left[0] <= right[0]:
            merged.append(left.pop(0))
        else:
            merged.append(right.pop(0))

    merged.extend(right if right else left)
    return merged

快速排序—— O ( n ) O(n) O(n)

def partition(alist, first, last):
    pivotvalue = alist[first]
    leftmark = first + 1
    rightmark = last
    done = False
    while not done:
        while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
            leftmark = leftmark + 1
        while alist[rightmark] >= pivotvalue and rightmark >= leftmark:
            rightmark -= 1
        if rightmark < leftmark:
            done = True
        else:
            alist[leftmark], alist[rightmark] = alist[rightmark], alist[leftmark]

        alist[first], alist[rightmark] = alist[rightmark], alist[first]

        return rightmark


def quickSort(alist):
    quickSortHelper(alist, 0, len(alist) - 1)


def quickSortHelper(alist, first, last):
    if first < last:
        splitpoint = partition(alist, first, last)
        quickSortHelper(alist, first, splitpoint - 1)
        quickSortHelper(alist, splitpoint + 1, last)

散列:Hashing

$ h(item)=item % 散列表大小$

itemHash Value
5410
264
935
176
770
319

完美散列函数

  • 压缩性
  • 易计算性
  • 抗修改性
  • 抗冲突性

散列函数设计

折叠法

  • 将数据项分段——(隔数翻转)
  • 将几段数据相加
  • 求余得到散列值

平方取中

  • 数据项平方计算
  • 取平方数中间两位求余

非数字项

  • ASCII码
  • 运算
def hash(astring, tablesize):
    sum = 0
    for pos in range(len(astring)):
        sum += ord(astring[pos])
    return sum % tablesize
  • 变位词:权重因子

冲突解决方案——再散列

开放定址

  • 线性探测
  • 跳跃式探测:
    • skip的值不能被散列表大小整除
  • 二次探测

r e h a s h ( p o s ) = ( p o s + s k i p ) % s i z e o f t a b l e rehash(pos)=(pos+skip)\%sizeoftable rehash(pos)=(pos+skip)%sizeoftable

数据项链

抽象数据类型:映射——ADT Map

class HashTable:
    def __init__(self):
        self.size = 11
        self.slots = [None] * self.size
        self.data = [None] * self.size

    def hashfunction(self, key):
        return key % self.size

    def rehash(self, oldhash):
        return (oldhash + 1) % self.size

    def put(self, key, data):
        hashvalue = self.hashfunction(key)
        # 未冲突
        if self.slots[hashvalue] == None:
            self.slots[hashvalue] = key
            self.data[hashvalue] = data
        # 替换
        else:
            if self.slots[hashvalue] == key:
                self.data[hashvalue] = data
            # 冲突
            else:
                nextslot = self.rehash(hashvalue)
                while self.slots[nextslot] != None and self.slots[nextslot] != key:
                    nextslot = self.rehash(nextslot)

                if self.slots[nextslot] == None:
                    self.slots[nextslot] = key
                    self.data[nextslot] = data
                else:
                    self.data[nextslot] = data

    def get(self, key):
        startslot = self.hashfunction(key)
        data = None
        stop = False
        found = False
        position = startslot
        while self.slots[position] != None and not found and not stop:
            if self.slots[position] == key:
                found = True
                data = self.data[position]
            else:
                position = self.rehash(position)
                if position == startslot:
                    stop = True
        return data

    def __getitem__(self, item):
        return self.get(item)

    def __setitem__(self, key, value):
        self.put(key, value)

最近在学数学,每天抽一点时间学算法,排序与查找终于看完了,还剩下树和图。
我看的是MOOC 北京大学 陈斌老师的《数据结构与算法python版》,都是干货,个人感觉比那些全是枯燥理论的好学一些

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZhShy23

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值