算法与数据结构

【Python数据结构与算法笔记day01】数据结构与算法(Python)

佐手、 提交于 2020-02-02 01:31:49
文章目录 数据结构与算法(Python) Why? 数据结构与算法(Python) Python数据结构与算法 1. 引入概念 1.1. 第一次尝试 1.2. 算法的提出 1.3. 第二次尝试 1.4. 算法效率衡量 1.5. 算法分析 1.6. 常见时间复杂度 1.7. Python内置类型性能分析 1.8. 数据结构 2. 顺序表 2.1. 顺序表的形式 2.2. 顺序表的结构与实现 2.3. 顺序表的操作 2.4. Python中的顺序表 3. 链表 3.1. 单向链表 3.2. 单项循环链表 3.3. 双向链表 4. 栈 4.1. 栈结构实现 5. 队列 5.1. 队列的实现 5.2. 双端队列 6. 排序与搜索 6.1. 冒泡排序 6.2. 选择排序 6.3. 插入排序 6.4. 快速排序 6.5. 希尔排序 6.6. 归并排序 6.7. 常见排序算法效率比较 6.8. 搜索 7. 树与树算法 7.1. 二叉树 7.2. 二叉树的遍历 Why? 我们举一个可能不太恰当的例子: 如果将最终写好运行的程序比作战场,我们码农便是指挥作战的将军,而我们所写的代码便是士兵和武器。 那么数据结构和算法是什么?答曰:兵法! 我们可以不看兵法在战场上肉搏,如此,可能会胜利,可能会失败。即使胜利,可能也会付出巨大的代价。我们写程序亦然:没有看过数据结构和算法,有时面对问题可能会没有任何思路

【Python数据结构与算法笔记day23】5.1. 队列的实现+操作

我是研究僧i 提交于 2020-02-02 01:15:57
文章目录 5.1. 队列的实现 队列的实现 操作 5.1. 队列的实现 队列的实现 同栈一样,队列也可以用顺序表或者链表实现。 操作 Queue() 创建一个空的队列 enqueue(item) 往队列中添加一个item元素 dequeue() 从队列头部删除一个元素 is_empty() 判断一个队列是否为空 size() 返回队列的大小 class Queue(object): """队列""" def __init__(self): self.items = [] def is_empty(self): return self.items == [] def enqueue(self, item): """进队列""" self.items.insert(0,item) def dequeue(self): """出队列""" return self.items.pop() def size(self): """返回大小""" return len(self.items) if __name__ == "__main__": q = Queue() q.enqueue("hello") q.enqueue("world") q.enqueue("itcast") print q.size() print q.dequeue() print q.dequeue() print

【Python数据结构与算法笔记day25】6. 排序与搜索+排序算法的稳定性

自古美人都是妖i 提交于 2020-02-02 01:03:57
文章目录 6. 排序与搜索 排序与搜索 排序算法的稳定性 6. 排序与搜索 排序与搜索 排序算法(英语:Sorting algorithm)是一种能将一串数据依照特定顺序进行排列的一种算法。 排序算法的稳定性 稳定性 :稳定排序算法会让原本有相等键值的纪录维持相对次序。也就是如果一个排序算法是稳定的,当有两个相等键值的纪录R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前。 当相等的元素是无法分辨的,比如像是整数,稳定性并不是一个问题。然而,假设以下的数对将要以他们的第一个数字来排序。 (4, 1) (3, 1) (3, 7)(5, 6) 在这个状况下,有可能产生两种不同的结果,一个是让相等键值的纪录维持相对的次序,而另外一个则没有: (3, 1) (3, 7) (4, 1) (5, 6) (维持次序) (3, 7) (3, 1) (4, 1) (5, 6) (次序被改变) 不稳定排序算法可能会在相等的键值中改变纪录的相对次序,但是稳定排序算法从来不会如此。不稳定排序算法可以被特别地实现为稳定。作这件事情的一个方式是人工扩充键值的比较,如此在其他方面相同键值的两个对象间之比较,(比如上面的比较中加入第二个标准:第二个键值的大小)就会被决定使用在原先数据次序中的条目,当作一个同分决赛。然而,要记住这种次序通常牵涉到额外的空间负担。 来源: CSDN 作者:

【Python数据结构与算法笔记day26】6.1. 冒泡排序

痴心易碎 提交于 2020-02-02 00:52:33
文章目录 6.1. 冒泡排序 冒泡排序 冒泡排序的分析 时间复杂度 冒泡排序的演示 6.1. 冒泡排序 冒泡排序 冒泡排序 (英语:Bubble Sort)是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。 冒泡排序算法的运作如下: 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。 针对所有的元素重复以上的步骤,除了最后一个。 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 冒泡排序的分析 交换过程图示(第一次): 那么我们需要进行n-1次冒泡过程,每次对应的比较次数如下图所示: def bubble_sort ( alist ) : for j in range ( len ( alist ) - 1 , 0 , - 1 ) : # j表示每次遍历需要比较的次数,是逐渐减小的 for i in range ( j ) : if alist [ i ] > alist [ i + 1 ] : alist [ i ] , alist [ i + 1 ] =

数据结构经典十套卷之十

拈花ヽ惹草 提交于 2020-02-02 00:46:23
一、选择题 (24 分 ) 1 . 下列程序段的时间复杂度为( )。 i=0 , s=0 ; while (s<n) {s=s+i ; i++ ; } 第一次执行完 s+=i s == 1 第二次 s == 3 == 1+2 第三次 s == 6 == 1+2+3 第四次 s == 10 == 1+2+3+4 第 k 次 1+2+3+4+...+k == k*(k+1)/2 那么当 k*(k+1)/2 >=n 的时候停止 也就是 k == ( 根号 (8*n+1) - 1 ) /2 关于 n 的表达式是 根号的 , 所以复杂度是 根号 n (A) O(n1/2) (B) O(n1/3) (C) O(n) (D)O(n2) 2 .设某链表中最常用的操作是在链表的尾部插入或删除元素,则选用下列( )存储方式最节省运算时间。 (A) 单向链表 (B) 单向循环链表 (C) 双向链表 (D) 双向循环链表 3 . 设指针 q 指向单链表中结点 A ,指针 p 指向单链表中结点 A 的后继结点 B ,指针 s 指向被插入的结点 X ,则在结点 A 和结点 B 插入结点 X 的操作序列为( )。 解: q s p (A) s->next=p->next ; p->next=-s ; (B) q->next=s ; s->next=p ; (C) p->next=s->next ; s-

【Python数据结构与算法笔记day27】6.2. 选择排序

不羁岁月 提交于 2020-02-02 00:41:16
文章目录 6.2. 选择排序 选择排序 选择排序分析 时间复杂度 选择排序演示 6.2. 选择排序 选择排序 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。 选择排序分析 排序过程: 红色表示当前最小值,黄色表示已排序序列, 蓝色表示当前位置。 def selection_sort ( alist ) : n = len ( alist ) # 需要进行n-1次选择操作 for i in range ( n - 1 ) : # 记录最小位置 min_index = i # 从i+1位置到末尾选择出最小数据 for j in range ( i + 1 , n ) : if alist [ j ] < alist [ min_index ] : min_index = j # 如果选择出的数据不在正确位置

【Python数据结构与算法笔记day28】6.3. 插入排序

我的未来我决定 提交于 2020-02-02 00:28:49
文章目录 6.3. 插入排序 插入排序 插入排序分析 时间复杂度 插入排序演示 6.3. 插入排序 插入排序 插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。 插入排序分析 def insert_sort ( alist ) : # 从第二个位置,即下标为1的元素开始向前插入 for i in range ( 1 , len ( alist ) ) : # 从第i个元素开始向前比较,如果小于前一个元素,交换位置 for j in range ( i , 0 , - 1 ) : if alist [ j ] < alist [ j - 1 ] : alist [ j ] , alist [ j - 1 ] = alist [ j - 1 ] , alist [ j ] alist = [ 54 , 26 , 93 , 17 , 77 , 31 , 44 , 55 , 20 ] insert_sort ( alist ) print ( alist ) 时间复杂度 最优时间复杂度:O(n) (升序排列,序列已经处于升序状态) 最坏时间复杂度:O(n2) 稳定性:稳定

【Python数据结构与算法笔记day30】6.5. 希尔排序

℡╲_俬逩灬. 提交于 2020-02-01 22:24:33
文章目录 6.5. 希尔排序 希尔排序 希尔排序过程 希尔排序的分析 时间复杂度 希尔排序演示 6.5. 希尔排序 希尔排序 希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。 希尔排序过程 希尔排序的基本思想是:将数组列在一个表中并对列分别进行插入排序,重复这过程,不过每次用更长的列(步长更长了,列数更少了)来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身还是使用数组进行排序。 例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样(竖着的元素是步长组成): 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 然后我们对每列进行排序: 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45

【Python数据结构与算法笔记day31】6.6. 归并排序

房东的猫 提交于 2020-02-01 20:19:31
文章目录 6.6. 归并排序 归并排序 归并排序的分析 时间复杂度 6.6. 归并排序 归并排序 归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。 将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。 归并排序的分析 def merge_sort ( alist ) : if len ( alist ) <= 1 : return alist # 二分分解 num = len ( alist ) / 2 left = merge_sort ( alist [ : num ] ) right = merge_sort ( alist [ num : ] ) # 合并 return merge ( left , right ) def merge ( left , right ) : '''合并操作,将两个有序数组left[]和right[]合并成一个大的有序数组''' #left与right的下标指针 l , r = 0 , 0 result = [ ] while l < len ( left ) and r < len ( right ) : if left [ l ] < right [ r ] :

【Python数据结构与算法笔记day33】6.8. 搜索

我怕爱的太早我们不能终老 提交于 2020-02-01 19:26:12
文章目录 6.8. 搜索 搜索 二分法查找 二分法查找实现 (非递归实现) (递归实现) 时间复杂度 6.8. 搜索 搜索 搜索是在一个项目集合中找到一个特定项目的算法过程。搜索通常的答案是真的或假的,因为该项目是否存在。 搜索的几种常见方法:顺序查找、二分法查找、二叉树查找、哈希查找 二分法查找 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。 二分法查找实现 (非递归实现) def binary_search ( alist , item ) : first = 0 last = len ( alist ) - 1 while first <= last : midpoint = ( first + last ) / 2 if alist [ midpoint ] == item : return True elif item < alist [