2.Python数据结构与算法分析课后习题(第二版)__chapter2

一、讨论题

1.O( n 2 n^2 n2)

2.O( n n n)

3.O( log ⁡ ( n ) \log (n) log(n))

4.O( n 3 n^3 n3)

2.O( n n n)

二、编程练习

1.设计一个实验,证明列表的索引操作为常数阶。

import timeit
import random
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

lenx = []
listy = []
color = ['c', 'b', 'g', 'r', 'm', 'y', 'k', 'w']

for i in range(10000, 1000001, 20000):
    t = timeit.Timer("x[random.randrange(%d)]" % i,"from __main__ import random, x")
    x = list(range(i))
    list_time = t.timeit(number=1000)
    print("%d, %10.3f" % (i, list_time))
    lenx.append(i)
    listy.append(list_time)
    ax = plt.gca()
    # 去掉边框
    ax.spines['top'].set_color('none')
    ax.spines['right'].set_color('none')
    # 移位置 设为原点相交
    ax.xaxis.set_ticks_position('bottom')
    ax.spines['bottom'].set_position(('data', 0))
    ax.yaxis.set_ticks_position('left')
    ax.spines['left'].set_position(('data', 0))
    listdot = plt.scatter(lenx, listy, c=color[3], edgecolors='r', label='list')
    plt.xlabel('lenth(list)')
    plt.ylabel('time(/s)')
    plt.title('List_index')
    plt.legend()
    plt.show()

在这里插入图片描述

2.设计一个实验,证明字典的取值操作和赋值操作为常数阶。

  1. 字典取值操作:dict.get(key)
import timeit
import random
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

lenx = []
dicty = []
color = ['c', 'b', 'g', 'r', 'm', 'y', 'k', 'w']

for i in range(10000, 1000001, 20000):
    t = timeit.Timer("x.get(random.randrange(%d))" % i, "from __main__ import random, x")    
    x = {j: None for j in range(i)}
    dict_time = t.timeit(number=1000)
    print("%d, %10.3f" % (i, dict_time))
    lenx.append(i)
    dicty.append(dict_time)
    ax = plt.gca()
    # 去掉边框
    ax.spines['top'].set_color('none')
    ax.spines['right'].set_color('none')
    # 移位置 设为原点相交
    ax.xaxis.set_ticks_position('bottom')
    ax.spines['bottom'].set_position(('data', 0))
    ax.yaxis.set_ticks_position('left')
    ax.spines['left'].set_position(('data', 0))
    dictdot = plt.scatter(lenx, dicty, c=color[3], edgecolors='r', label='dict')
    plt.xlabel('lenth(dict)')
    plt.ylabel('time(/s)')
    plt.title('dict_assign()')
    plt.legend()
    plt.show() 

在这里插入图片描述
2. 字典赋值操作:dict[key] = value

	# t = timeit.Timer("x.get(random.randrange(%d))" % i, "from __main__ import random, x")
    t = timeit.Timer("x[random.randrange(%d)] = random.randrange(%d)" % (i,i), "from __main__ import random, x")

在这里插入图片描述

3.列表和字典比较del 操作的性能

import timeit
import random
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

lenx = []
listy = []
dicty = []
color = ['c', 'b', 'g', 'r', 'm', 'y', 'k', 'w']

for i in range(1000000, 100000001, 1000000):
    t = timeit.Timer("del x[random.randrange(%d)]" % i, "from __main__ import random, x")

    x = list(range(i))
    list_time = t.timeit(number=1)
    x = {j:None for j in range(i)}
    dict_time = t.timeit(number=1)
    print("%d, %15.5f, %15.5f" % (i, list_time, dict_time))

    lenx.append(i)
    listy.append(list_time)
    dicty.append(dict_time)
    ax = plt.gca()
    # 去掉边框
    ax.spines['top'].set_color('none')
    ax.spines['right'].set_color('none')
    # 移位置 设为原点相交
    ax.xaxis.set_ticks_position('bottom')
    ax.spines['bottom'].set_position(('data', 0))
    ax.yaxis.set_ticks_position('left')
    ax.spines['left'].set_position(('data', 0))
    listdot = plt.scatter(lenx, listy, c=color[3], edgecolors='r', label='list')
    dictdot = plt.scatter(lenx, dicty, c=color[1], edgecolors='b', marker='^', label='dict')
    plt.xlabel('lenth(list&dict)')
    plt.ylabel('time(/s)')
    plt.title('List&Dict_del_analysis')
    plt.legend()
    plt.show()

在这里插入图片描述

4.给定一个数字列表,其中的数字随机排列,编写一个线性阶算法,找出第k 小的元素,并解释为何该算法的阶是线性的。

&

5.针对前一个练习,能将算法的时间复杂度优化到O( n l o g n n log n nlogn)吗?

import timeit
import random
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

def findkMin(x, k):
    if k == 0:
        return -1
    k -= 1
    while k:
        temp = x[0]
        j = 0
        for i in range(len(x)):
            if temp > x[i]:
                temp = x[i]
                j = i
        del x[j]
        k -= 1
    temp = x[0]
    for i in range(len(x)):
        if temp > x[i]:
            temp = x[i]
    return temp

def findkMin1(x, k):
    # if k == 0:
    #     return -1
    x.sort()
    return x[k-1]

lenx = []
find1y = []
find2y = []
color = ['c', 'b', 'g', 'r', 'm', 'y', 'k', 'w']

if __name__ == '__main__':
    x1 = [1,3,2,4]
    x = list(range(100))
    np.random.shuffle(x)
    print(x)
    print(findkMin1(x,0))

    for i in range(100, 200000, 1000):
        t1 = timeit.Timer("findkMin(x,random.randrange(%d))" % i, "from __main__ import random, x,findkMin")
        t2 = timeit.Timer("findkMin1(x,random.randrange(%d))" % i, "from __main__ import random, x,findkMin1")
        x = list(range(i))
        np.random.shuffle(x)
        findtime1 = t1.timeit(number=1)
        x = list(range(i))
        np.random.shuffle(x)
        findtime2 = t2.timeit(number=1)
        print("%d, %15.6f,%15.6f" % (i, findtime1, findtime2))
        lenx.append(i)
        find1y.append(findtime1)
        find2y.append(findtime2)
        ax = plt.gca()
        # 去掉边框
        ax.spines['top'].set_color('none')
        ax.spines['right'].set_color('none')
        # 移位置 设为原点相交
        ax.xaxis.set_ticks_position('bottom')
        ax.spines['bottom'].set_position(('data', 0))
        ax.yaxis.set_ticks_position('left')
        ax.spines['left'].set_position(('data', 0))
        plt.scatter(lenx, find1y, c=color[3], edgecolors='r', label='FindKMin1')
        plt.scatter(lenx, find2y, c=color[1], edgecolors='b', marker='^', label='FindKMin2')
        plt.xlabel('lenth(list)')
        plt.ylabel('time(/s)')
        plt.title('FindKMin_analysis')
        plt.legend()
        plt.show()

在这里插入图片描述
使用排序方法的**findkmin()**时间复杂度并不是常数,如下:
在这里插入图片描述

三、总结

主要学习了

1.大O记法,
2.时间复杂度,
3.python绘制散点图,
4.如何对简单的python程序进行基准测试
等。

  • 5
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值