马上要把大话数据结构这本书看完啦,现在已经对数据结构有了一种系统上的了解,后面的事情就疯狂练习力扣上的编程题目啦,第九章是本书的最后一章,却是以前我学数据结构最先学的部分-----排序。

排序

网页搜索之后的排序,商品页面的排序,是如何做到的呢?

本章将介绍7种排序算法:

冒泡排序,简单选择排序,直接插入排序属于简单算法。

快速排序,归并排序(merge sort),希尔排序,堆排序属于改进算法。

本文中都是升序排序哦~

1.冒泡排序

#bubble sorted
def bubble(array):if array == None or len(array) == 0:return -1for i in range(len(array)-1):for j in range(len(array)-1):if array[j] > array[j+1]:array[j],array[j+1] = array[j+1],array[j]return array

时间复杂度:o(n^2)

空间复杂度:o(1)

2.简单选择排序

选择一个数作为最小数,(比如选第一个数作为min),在后续数组中找到最小的数字,并交换位置。若没有,跳到第二个数字,继续进行比较。

代码如下:

#selection sort
def select(array):if array == None or len(array) == 0:return -1for i in range(len(array)-1):min_index = ifor j in range(i,len(array)):if array[min_index] > array[j]:array[min_index],array[j] = array[j],array[min_index]return array

时间复杂度:o(n^2)

空间复杂度:o(1)

3.直接插入排序

插入排序(Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

所以insert需要的时间复杂度是o(n),排序(找插入空位)的时间复杂度是o(n),当然如果用binary search找空位的时间复杂度是o(logn),总体的时间复杂度为o(n^2)或者是o(nlogn)。

代码如下:

def insert(list_a):for i in range(1,len(list_a)):cur = list_a[i]k = iwhile cur < list_a[k-1] and k > 0:#寻找空位list_a[k] = list_a[k-1]k -= 1                        #k记录的当前空位的位置list_a[k] = cur#插入return list_a

插入排序由于需要挪动空位后的元素,所以需要游标(存储现在正在进行插入的数据元素),需要记录元素下标。寻找插入空位这个代码得记住,感觉可以用在其他地方。

前三种方法都是简单的排序算法,比较他们的最坏的时间复杂度(序列初始为逆序),直接插入算法性能比冒泡和简单选择排序的性能要好。

4 堆排序(heap)

堆是具有下列性质的完全二叉树:

每个节点的值都大于或等于其左右孩子节点的值,叫大顶堆;

每个节点的值都小于或等于其左右孩子节点的值,称为小顶堆。

堆排序算法的步骤:

以大顶堆为例

1 将待排序的序列构成大顶堆。

2 此时最大值就是堆顶的根节点,将其移走(其实是将其与堆数组的末尾元素交换,此时末尾元素就是最大值)

3 将剩余的n-1个序列重新构造成一个堆,这样就可以得到从小到大的排序的有序序列。

要解决的关键问题就是如何建立堆!

建立堆(以实现小顶堆为例)

如何用数组来表示一个完全二叉树?

完全二叉树孩子节点和父亲节点的数组索引关系是酱紫的:

left_node = parent_node * 2 + 1

right_node = parent_node * 2 + 2

parent_node = (child_node - 1) // 2

所以需要实现让完全二叉树的每个节点都小于孩子节点才能建立小顶堆。

将一个随机数组变成小顶堆的python代码如下:

def min_heap(array,i):left = i*2+1right = i*2+2smaller = iif left < len(array) and array[left] < array[smaller]:smaller = leftif right < len(array) and array[right] < array[smaller]:smaller = rightif smaller != i:array[smaller],array[i] = array[i],array[smaller]min_heap(array,smaller)def build_heap(arr):for i in range(len(arr)//2,-1,-1):min_heap(arr,i)return arr

时间复杂度o(nlogn)。

如果你要往已经生成的小顶堆中加入数据元素:

def push(array,i):
#这里的i是输入序列的最后一位的索引值,也是你要插入的数据。parent = (i-1)//2large = iif parent >= 0 and array[parent] > array[i]:large = parentif large != i:array[large],array[i]= array[i],array[large]push(array,large)

时间复杂度都是o(logn)。

python中heapq包,专门完成堆的一些操作。

import heapq

heap = []                  #生成的是小顶堆

heappush(heap,item)

item = heappop(heap)

item = heap[0]

heapify(x) #将list转换为heap

item = heapreplace(heap,item) #先pop再插入item

有了这些可以应用它做一些编程题目:

比如实现堆排序,寻找序列中的最小k项,合并k个有序序列等。

5 归并排序

先分割序列,再将分割后的序列进行合并

def merge(a,b):c = []index_a,index_b = 0,0while index_a < len(a) and index_b < len(b):if a[index_a] > b[index_b]:c.append(b[index_b])index_b += 1elif a[index_a] <= b[index_b]:c.append(a[index_a])index_a += 1if index_a < len(a):c.extend(a[index_a:])if index_b < len(b):c.extend(b[index_b:])return cdef merge_sort(list_a):if len(list_a) == 0 or len(list_a) == 1:return list_amid = len(list_a)//2a = merge_sort(list_a[:mid])b = merge_sort(list_a[mid:])return merge(a,b)

时间复杂度:o(nlogn)

6 快速排序

通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。这是不稳定的算法,因为时间复杂度最坏o(n^2),最好和平均情况是o(nlogn)。

def paixu(a,b):c = a+bp = (len(a)+len(b))//2end = len(a)+len(b)-1for start in range(p):for i in range(p, end + 1):if c[start] >= c[i] and start <= len(a) - 1:c[start], c[i] = c[i], c[start]return cdef q_paixu(a):if len(a) <= 1:return aelse:p = len(a)//2j = q_paixu(a[0:p])b = q_paixu(a[p:len(a)])return paixu(j,b)

7 希尔排序

它就是直接插入排序的进阶、这个网址解释的很清楚。

https://blog.csdn.net/u014745194/article/details/72783357

关于这七个排序算法的稳定性和时间复杂度:

https://www.cnblogs.com/nannanITeye/archive/2013/04/11/3013737.html

选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,

冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。

首先,排序算法的稳定性大家应该都知道,通俗地讲就是能保证排序前两个相等的数据其在序列中的先后位置顺序与排序后它们两个先后位置顺序相同。再简单具体一点,如果A i == A j,Ai 原来在 Aj 位置前,排序后 Ai  仍然是在 Aj 位置前。

插入排序:第n趟前n+1个有序

选择排序:第n趟前n个位置正确

快速排序:第n趟有n个元素位置正确

堆排序:第n趟前或后n个位置正确

大话数据结构第九章---排序相关推荐

  1. 读书笔记_大话数据结构第九章_排序

    排序 冒泡[O的n方] 简单选择[O的n方]

  2. 数据结构-第九章 内部排序-知识点总结1

    第九章 内部排序 排序:重点在于对于记录的关键字进行排序,得到按关键字有序记录序列 分为:     A.内部排序: 排序过程在内存中进行      B.外部排序: 待排序记录数据量过大,需要借助外部存 ...

  3. 数据结构-第九章 内部排序-知识点总结2

    选择类排序: 1.简单选择排序: 直接从数组中选择最小的记录和第一个记录交换位置,循环. 示例代码如下: void SelectSort(int r[], int b){int i, j, k;int ...

  4. 大话数据结构:拓扑排序

    基础介绍 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G), ...

  5. 大话数据结构第一章理解

    一.概念          1.1 数据概念 数据:计算机能识别的能运算的符号,各种数据对象的集合--可以简单理解为各种类型的数组的集合. 数据对象:是性质相同的同一类型的数据元素的集合--可以简单理 ...

  6. 大话数据结构及JAVA数据结构阅读笔记

    目录 一.大话数据结构随书阅读笔记 第一章 数据结构概述 第二章  算法概述 第三章 线性表 第四章 栈与队列 第五章 串 第六章 树 第七章 图 第八章 查找 第九章 排序 二.大话数据结构思维导图 ...

  7. 大话数据结构(一)数据结构相关概念

    目录 数据结构的基本概念和术语 1.数据 2.数据元素 3.数据项 4.数据对象 逻辑结构和物理结构 抽象数据类型 总结 在这里说一下,大学的时候学习过数据结构,但是根本不深入,现在重新学习一遍数据结 ...

  8. 数据结构—排序(第九章)

    目录 1. 排序的基本概念与分类 1.1 排序的稳定性 1.2 内排序与外排序 1.3 排序用到的结构与函数 2. 冒泡排序 2.1 最简单排序实现 2.2 冒泡排序算法 2.3 冒泡排序优化 2.4 ...

  9. 大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第1章数据结构绪论 1 第2章算法 17 第3章线性表 41 第4章栈与队列 87 第5章串 123 第6章树 149 第7章图 21

    大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第1章数据结构绪论 1 第2章算法 17 第3章线性表 41 第4章栈与队列 87 第5章串 123 第6章树 149 第7章图 211 第 ...

最新文章

  1. MATLAB_图形学_形态学课程II
  2. sysbench tpcc-mysql_使用sysbench来测试MySQL性能的详细教程
  3. 2017网易云创大会教育论坛,等你!
  4. 2010年北京大学计算机研究生机试真题
  5. 男人的快乐可以多简单?
  6. Three Bags CodeForces - 1467C
  7. 前端学习(1976)vue之电商管理系统电商系统之解决attr_val为空
  8. L1-041 寻找250-PAT团体程序设计天梯赛GPLT
  9. 让你提前认识软件开发(40):既要写好代码,又要写好文档
  10. 操作系统锁的实现方法有哪几种_Java并发之Monitor实现
  11. 软件架构的六大设计原则
  12. java经典编程练习题_java笔试经典练习题及答案
  13. 七年级计算机学期教学要求,七年级信息技术教学工作总结
  14. php 验证码数字英文的,PHP 创设扭曲英文验证码
  15. 安装爬虫框架Scrapy,安装后运行不了~
  16. 处理unity第一第三人称游戏中的摄像机穿墙的问题
  17. 通过组策略设置输入法
  18. uboot源码分析(基于S5PV210)之启动第一阶段
  19. 什么样的软件算是功能安全软件?
  20. 专业解析CCD和CMOS摄像机哪个更优秀

热门文章

  1. 手机app兼容性测试点分析(通用)
  2. 强大的Js树型控件Dtree使用详解
  3. 机器学习-数据挖掘中常用的数据清洗方法
  4. 【泛微ecology9 实战教程】流程实战-费用报销
  5. zipline中扩展上交所交易日历SHStockCalendar
  6. Dead Reckoning: 在网络游戏中消除延时影响
  7. LeetCode 90. 子集 II【数组,回溯算法,排序去重】
  8. 微信小程序 循环原数组并追加新元素(删除数组指定元素)
  9. ELK日志分析系统概述及部署
  10. ubuntu安装Miniconda