《算法图解》读书笔记-2选择排序(数组与链表)

Rosalia ·
更新时间:2024-09-20
· 834 次阅读

数组和链表

链表:链表中的元素可储存在内存的任何地方,也就是说可以不连续。链表的每个元素都存储了下一个元素的地址,从而使一系列随机的内存串在一起。它的优势是插入方面比较快。
链表

补充知识:其实链表分为单链表和双链表(此图出处)。
单、双链表

说出来你可能不信对于链表的介绍就像开玩笑一样的结束了。。。。。。
但是为了加强下印象简单实现个单链表结构,大佬勿喷。。。

class Node(object): def __init__(self, value=None, next=None): '''首先需要个节点,包括value和next属性''' self.value, self.next = value, next class LinkedList(object): '''简单的实现下append方法''' def __init__(self, maxsize=None): self.maxsize = maxsize #链表最大长度 默认为None表示无限制(只要内存够用) self.length = 0 #长度 self.root = Node() #定义根节点(链表起始) self.tailnode = None #尾结点 def __len__(self): return self.length def append(self, value): if self.maxsize is not None and len(self) >= self.maxsize:#首先判断一波链表是否满了 raise Exception("Full") node = Node(value) #将加入的值 定义成节点 tailnode = self.tailnode #获取到尾结点 if tailnode is None: #判断是否只有root节点 self.root.next = node #如果只有根结点正好 根节点直接指向该值 else: self.tailnode.next = node #否则尾结点指向该值 self.length += 1 self.tailnode = node #一定要更新尾结点 数组

数组:其实数组相对好理解,就是将一组数据连续存储,数组的元素是带着标号的,地址是互相挨着的。

数组

链表和数组的操作运行时间如下:
对比如上

如果删除元素,链表只需要修改前一个元素指向的地址即可。而数组在删除元素后,必须将后面的元素向前移动。 读取的时候链表只能重头访问所以查询不如数组灵活。

##选择排序

问题:假设计算机内存储了许多音乐,并且记录了被播放的次数,需要按照次数进行排序该如何去做?
如图

首先考虑最笨的做法(选择排序):每次都看一遍所有数据,假设一共有n个数据,需要看n次并且每次看n个数据,由于O(n)表示的是将每个数据看一遍,所以此操作复杂度为O(n2n^2n2)。

# encoding: utf-8 # @Author : NanG # create on 2020-03-17 08:59 from datetime import datetime import numpy as np def findSmallest(arr): smallest = arr[0] #最小值(也可以最大值) smallest_index = 0 #最小值索引 for i in range(1, len(arr)): if arr[i] < smallest: smallest = arr[i] smallest_index = i return smallest_index def selectionSort(arr): startime = datetime.timestamp(datetime.now()) newArr = [] for i in range(len(arr)): smallest = findSmallest(arr) newArr.append(arr.pop(smallest)) endtime = datetime.timestamp(datetime.now()) return newArr, endtime-startime def test_selectionSort(): arrs1 = np.random.randint(10, size=100) test10, time10 = selectionSort(list(arrs1)) print("time100:{}".format( time10)) print(test10) arrs2 = np.random.randint(10, size=1000) test100, time100 = selectionSort(list(arrs2)) print("time100:{}".format( time100)) arrs3 = np.random.randint(10, size=10000) test1000, time1000 = selectionSort(list(arrs3)) print("time10000:{}".format(time1000)) arrs4 = np.random.randint(10, size=100000) test1000000, time1000000 = selectionSort(list(arrs4)) print("time100000:{}".format(time1000000)) arrs4 = np.random.randint(10, size=1000000) test1000000, time1000000 = selectionSort(list(arrs4)) print("time1000000:{}".format(time1000000)) if __name__ == '__main__': test_selectionSort()

本来想用传说中的五点确定图像的方法(初中画图基础),但是1000000的计算了一个多小时还没结束,有些心疼我的小笔记本就没做完。结果如下(建议用pytest进行单测):

time100:0.0004849433898925781 time1000:0.049310922622680664 time10000:4.410588026046753 time100000:453.7767798900604 time1000000:>1小时
作者:老练的小白



选择排序 选择 链表 算法 排序 读书 数组

需要 登录 后方可回复, 如果你还没有账号请 注册新账号