惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google Online Security Blog
Google Online Security Blog
S
Security @ Cisco Blogs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
人人都是产品经理
人人都是产品经理
The Hacker News
The Hacker News
W
WeLiveSecurity
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
博客园 - 司徒正美
雷峰网
雷峰网
L
LINUX DO - 最新话题
博客园 - 叶小钗
云风的 BLOG
云风的 BLOG
The Last Watchdog
The Last Watchdog
V2EX - 技术
V2EX - 技术
S
Security Affairs
有赞技术团队
有赞技术团队
月光博客
月光博客
T
Threatpost
T
Tor Project blog
O
OpenAI News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V
V2EX
Know Your Adversary
Know Your Adversary
Project Zero
Project Zero
博客园 - 三生石上(FineUI控件)
D
Docker
AWS News Blog
AWS News Blog
AI
AI
P
Proofpoint News Feed
K
Kaspersky official blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
S
Securelist
F
Fortinet All Blogs
F
Full Disclosure
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
量子位
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
P
Palo Alto Networks Blog
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
美团技术团队
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
MyScale Blog
MyScale Blog

Posts on WKLKEN THINKING

apisix 中的 lrucache apisix 中的服务发现机制 apisix 中的负载均衡 apisix etcd机制 聊聊框架 关于 k8s 的 zero downtime deployment 一些建议 apisix 遇到的一些问题 关于在除夕前一天换了一个洗衣机的故事 Django DRF 性能优化 DRF 的一些实践 Part1: Serializer DRF继承关系图 Better Code: 关于接口的灵活性 新的仓库: wklken/naming 缓存使用的一些经验 Better Code: 抽象: 可扩展性与可维护性的抉择 Better Code: 异常时, 该提示用户哪些信息? Better Code: 更好的异常日志打印 Go: some libs Go: go-redis/cache升级的坑 Go: logrus性能提升 Go: gin validation 远程办公的一点总结 Go: 开发过程中的一些bug 项目管理实践: 风险驱动开发 Go: 一种error wrap调用链处理方式 漫谈技术选型 Go: 基于 apitest 做handler层单元测试 Go: go-sql-driver interpolateparams参数优化 [分享]深度工作 你需要更多的思考时间 Django项目重构小结 工作七年小结: 学习,生活及其他 [分享]bash日常: bash-utils 极客时间推广海报 2017总结: 予时光以意义 k8s APIServer源码: api注册详细细节 k8s APIServer源码: api注册主体流程 k8s APIServer源码: 服务启动 k8s APIServer源码: go-restful框架 重构 - 读书笔记(Python示例) 写给新人的沟通建议 vim 杂谈 - 关于快速编辑 vim 杂谈 - 关于移动 读书笔记-重构: 章11 处理概括关系 读书笔记-重构: 章10 简化函数调用 读书笔记-重构: 章9 简化表达式 读书笔记-重构: 章8 重新组织数据 读书笔记-重构: 章7 在对象之间搬移特性 读书笔记-重构: 章6 重新组织函数 Python 代码规范小结 [分享]关于vim ElasticSearch集群部署文档 Logstash+ElasticSearch处理mysql慢查询日志 [分享]关于代码调试DE那些事 Logstash+ElasticSearch+Kibana- 实现相对通用的数据收集分析 ELK维护的一些点(二) [分享]Python源码剖析-数据结构 一些Centos Python生产环境的部署命令 摘录<<6个月学会任何一种外语>> ELK 维护的一些点 也许是一个新的开始 一些vim的个性化配置 读书笔记-调试九法 这段时间的一些想法 Python 源码阅读 - 垃圾回收机制 我为什么要写博客 APUE笔记-第一章 UNIX基础知识 Python源码阅读-闭包的实现 Python源码阅读-内存管理机制(二) Python源码阅读-内存管理机制(一) Python-基础-数据结构小结 '活动'设计的一些trick 一些简单的Python测试题 我的tmux配置及说明【k-tmux】 Review and Restart 工作四周年小结 vim插件: surround & repeat[成对符号编辑] vim插件: gundo[时光机] vim插件: expand-region[区域选中] vim插件: quickrun[快速执行] vim插件: trailing-whitespace[行尾空格处理] vim插件: closetag[成对标签补全] vim插件: ctrlp[文件搜索] vim插件: airline[状态栏增强] vim插件: theme[主题] vim插件: tagbar[大纲式导航] vim插件: nerdcommenter[快速注释] vim插件: rainbow_parentheses[括号高亮] vim插件: syntastic[语法检查] vim插件: delimitmate[符号自动补全] vim插件: matchit[成对标签跳转] vim插件: easy-align[快速对齐] vim插件: multiple-cursors[多光标操作] vim插件: vim-signature[快速标记跳转] vim插件: easymotion[快速跳转] vim插件: vundle[管理插件] Elasticsearch几个问题的解决 分享一份 Vim 简介PPT k-vim 更新9.0版本 关于知识管理工具的思考
数据结构&算法实践—【排序|交换排序】冒泡排序及改进
2012-05-16 · via Posts on WKLKEN THINKING

排序»交换排序»冒泡排序

List:

0.概念+伪代码+示例分析
1.基本冒泡排序
2.冒泡排序改进1
3.冒泡排序改进2——局部冒泡排序
4.Question
  1. start

基本概念:

维基百科http://zh.wikipedia.org/wiki/%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F

伪代码:(来自百科)

function bubblesort (A : list[1..n]) {
    var int i, j;
    for i from n downto 1 {
        for j from 0 to i-1 { 
            if (A[j] > A[j+1])
                swap(A[j], A[j+1])
        }
    }
}

简要排序过程的示例:(基本冒泡排序)

初始数组

[50, 10, 30, 20, 40, 60]

第一轮:

cmp 50 10 -> change [10, 50, 30, 20, 40, 60]
cmp 50 30 -> change [10, 30, 50, 20, 40, 60]
cmp 50 20 -> change [10, 30, 20, 50, 40, 60]
cmp 50 40 -> change [10, 30, 20, 40, 50, 60]
cmp 50 60 -> nochange

第二轮:

[10, 30, 20, 40, 50, 60]
cmp 10 30 -> nochange
cmp 30 20 -> change [10, 20, 30, 40, 50, 60]
cmp 30 40 -> nochange
cmp 40 50 -> nochange

第三轮

[10, 20, 30, 40, 50, 60]
cmp 10 20 -> nochange
cmp 20 30 -> nochange
cmp 30 40 -> nochange

第四轮:

[10, 20, 30, 40, 50, 60]
cmp 10 20 -> nochange
cmp 20 30 -> nochange

第五轮:

[10, 20, 30, 40, 50, 60]
cmp 10 20 -> nochange
[10, 20, 30, 40, 50, 60]

cmp count 15

即共进行n-1=5轮冒泡,比较次数为 (n-1) + (n-2) + ……+1 =n*(n-1)/2=15

  1. start

基本冒泡排序python实现:

:::python
#冒泡排序,base
def bubble(l):
    print l
    for i in range(len(l)-1,0,-1):
        #每一轮冒泡,第 i个 元素会是最大的(i<=size-1)
        for j in range(i):
        #从0到i-1,比较 current 和next,若current > next,对换
        if l[j] > l[j+1]:
            l[j], l[j+1] = l[j+1], l[j]
        print l
  1. start

问题:在基本冒泡排序的示例中,第三轮结束时,其实已经排序完成了,但是还是一直会持续后面几轮的排序,这就带来了无谓的浪费.

改进:加入标志,判断,若是上一轮不存在数据交换,代表上一轮已经是排序的了,退出

比较次数:12

:::python
#改进1:  当某一轮跑完,不存在数据交换时,代表已排序完成,此时退出
def bubble_improve(l):
    flag = 1 #初始标志,1
    for i in range(len(l)-1,0,-1):
        #若是上一轮存在数据交换,继续执行排序
        if flag:
            flag = 0 #每一轮初始,交换标志为0
            for j in range(i):
                if l[j] > l[j+1]:
                    l[j], l[j+1] = l[j+1], l[j]
                    flag = 1 #存在交换,标志置为1
            print l
        #否则,代表目前序列已经排序完毕了
        else:
            break
  1. start

局部冒泡排序:(资料不多,不知道自己理解对不对)

序列[ a b c d ] 冒泡到了b,此时a小于b,比较b c,若是 b 大于 c,交换b c 得到 [ a c b d ]

通常冒泡排序一直往前,继续比较b和d

其实,在完成一次数据交换时(b<->c),可以反向增加一次比较,(a 和 c) ,若是a>c,再次交换得到[ c a b d] ——反向做一次冒泡

(百度百科有几行….凑合看)

定义:可以在一趟全局扫描中,对每一反序数据对进行局部冒泡排序处理,称之为局部冒泡排序 局部冒泡排序与冒泡排序算法具有相同的时间复杂度,并且在正序和逆序的情况下,所需的关键字的比较次数和移动次数完全相同。 由于局部冒泡排序和冒泡排序的数据移动次数总是相同的,而局部冒泡排序所需关键字的比较次数常少于冒泡排序,这意味着局部冒泡排序很可能在平均比较次数上对冒泡排序有所改进 当比较次数较少的优点不足以抵消其程序复杂度所带来的额外开销,而当数据量较大时,局部冒泡排序的时间性能则明显优于冒泡排序 (查看百度百科,有张对比图)

简而言之,正向冒泡时,若存在数据交换,反向再进行一次冒泡比较。减少了比较次数

why?

假设在第二轮冒泡 到了50 <-> 30

[10, 20, 40, 50, 30, 60]
带标志位冒泡:cmp 50 30 ->change  [10, 20, 40, 30, 50, 60]     count+=1
第三轮 count+= 4      (10,20) (20,40) (40,30) (40,50)
第四轮count +3   (10,20) (20,30) (30,40)     (无数据交换了,退出)

共 8次

局部冒泡: cmp 50 30 ->change  [10, 20, 40, 30, 50, 60]    count+=1
cmp 40 30 -> change  [10, 20, 30, 40,  50, 60]  count+=1
第三轮 count+=4(无数据交换了,退出)

共 6次

:::python
#改进2: 局部冒泡排序
def bubble_improve2(l):
    print l
    flag = 1
    scope = len(l)-1
    for i in range(scope,0,-1):
        if flag: 
            flag = 0
            for j in range(i):
                inner_flag = 0 #本次是否存在数据交换标志,每次置空,不复用flag的原因是如果第一次就交换了,会造成不必要的局部冒泡
                if l[j] > l[j+1]:
                    l[j], l[j+1] = l[j+1], l[j]
                    flag = 1
                    inner_flag = 1
                #从前往后的冒泡,j与j+1发生数据交换了,反向冒泡 j-1 j
                #若是本轮存在数据交换,局部排序处理 j-1  j j+1,保证是从小到大的 
                if inner_flag:
                    if j - 1 > 0:
                        if l[j-1] > l[j]:
                            l[j-1], l[j] = l[j],l[j-1]
            print l
        else:
        break

局部冒泡排序一个示例过程:

[50, 10, 30, 20, 40, 60]
cmp 50 10 -> change [10, 50, 30, 20, 40, 60]
cmp 50 30 -> change [10, 30, 50, 20, 40, 60]
cmp 50 20 -> change [10, 30, 20, 50, 40, 60]
inner cmp 30 20
inner change [10, 20, 30, 50, 40, 60]
cmp 50 40 -> change [10, 20, 30, 40, 50, 60]
inner cmp 30 40
cmp 50 60 -> nochange
[10, 20, 30, 40, 50, 60]
cmp 10 20 -> nochange
cmp 20 30 -> nochange
cmp 30 40 -> nochange
cmp 40 50 -> nochange
[10, 20, 30, 40, 50, 60]
  1. start

仅是贴出来,权当复习,木有答案,后续补充

A.冒泡排序概念,过程描述?

B.最差,平均,最优 时间复杂度?

C.空间复杂度?

D.是否是稳定排序?

E.如何改进?

F.局部冒泡排序原理?

G.适用场景,什么情况下最优,什么情况下最差?

—————————————– END ————————————————-

P.S.

这是第一篇,有什么不对请指正哈,欢迎补充任何问题和答案

白天上班加班(SDET),夜深敲代码(python,java…….),会坚持写完的