go语言快速排序 go语言map排序

alphago是什么语言开发的 Android以Java为编程语言,使接口到功能,都有层出不穷的变化 , 其中Activity等同于J2ME的MIDlet,一个 Activity 类(class)负责创建视窗(window) , 一个活动中的Activity就是在 foreground(前景)模式,背景运行的程序叫做Service 。两者之间.
英语作文human vs alphago
Google's artificial intelligence-driven AlphaGo sofare program will challenge Ke Jie, the world's top professional Go player, at China's Future of Go Summit in May. The prospect of this petition beeen human and artificial intelligence has captured the attention of the Chinese public, where the game was invented more than 2,500 years ago, and driven interest in Google's DeepMind machine learning method that developed AlphaGo.We believe a machine could never replace a person as an adversary in future.It's a cold machine without blood, while we have spiritual power.
怎么看待alphago的这个失误
谷歌非常有谋略,先让阿尔法狗连赢三次,奠定胜利的事实,展示人工智能的厉害!让人恐慌! 然后 , 谷歌让阿尔法狗输棋给李世石,以明白无误的方式告诉恐慌的人们:不要害怕,我们掌控着人工智能的! 如果人工智能把人逼上绝路,人工智能产业就会遭到人们的封杀! 谷歌输一局 , 缓和局面 。
中日韩还有成千上万围棋学习者和相关从业人员,Google是商业公司,当然不会把事情做绝,肯定会考量这方面的因素 。
比赛结束,alphago四比一完胜李世石,仅胜利的一局有很多人认为是谷歌为了让alphago有世界排名而故意输的一局,因为如果一个棋手一直连胜,是没有世界排名的,输了一局才有排名,按照官方发布目前alphago排名世界第二,中国小将柯杰世界第一 。
如何评价AlphaGo的围棋水平
AlphaGo能够战胜李世石的确证明了他是有职业顶尖的水平,也就是的职业九段,其计算能力与局部分析能力超越职业九段!可是,AlphaGo要想拿到职业冠军是基本不可能的,因为它不会自主学习,需要输入对方的棋谱才能占优优势 。
此外,在局部与大局的判断上,AlphaGo是有缺陷的 , 如果是遇到巅峰时期的李昌镐或是聂老聂卫平先生,折现缺点就会被无限放大 。
总而言之,现在它的对局还是太少了,需要更多的对局与研究,看不同的棋风与派别对它的胜率的影响,究竟综合实力是多少,还需要考究!
人工智能的利与弊作文结尾?
机器人还是不一样,完全不受外界与情绪的任何干扰,坐下便拼杀起来 。
它的芯片经历了十年换代 , 几乎对所有围棋套路了如指掌,面对我的每一步棋,都能识破我的意图 , 找到最合适的解决方法,更别提失误了,而我却并不急躁,慢慢悠悠 , 心中早已打好了算盘 。
这盘棋下得出奇得慢,半个月 , 1个月,我也并不着急,AlphaGo作为一个高智商机器人也能准确捕捉到我的所有需求,我们不仅棋下得有条不紊,它更是端茶倒水,冷风热气,无微不至 。
这棋转眼便下了三个月,我打定主意,心中不急,这AlphaGo作为机器人便更不知着急了,倒是观众们耐心早已磨完,他们催促也好,咒骂也罢,我自不动,每日只想一步棋 , 每日只下一步棋 , 但我内心却从未平静 。
我等待着机会 , 更等待着灵感 , 后来已无人有心再关注这场比赛,我的心中也越发平静了 。
直到那一天 , 我依如往常早早起床,一边诵读着道德经,一边在园中散步 。
突然,一个灵感穿过我的头脑,一个阴阳卦象图转变为了一幅棋盘,“我若击杀这个未曾关注过的棋点,他岂不再无机会?”我哈哈大笑,回到棋盘前,下了这一步我等了许久的棋,不出所料,AlphaGo一筹莫展,投子认输 。
世界轰动,人们重新将关注点拉到了我身上 , 我也不过多解释,手放背后:“道可道,非常道……”我先人一盘棋能下几个月,参悟世间之道,下的是道,而非棋,这岂是一个机器人能理解的?”从此之后,人们不再挑战AlphaGo,亦不再过度追求棋中胜负 , 他们好像也沉静了下来,回归了这项运动最本质的精髓 , 思考人生,思考自然 , 思考世界,找到了心中的那片桃花源 。
如何评价柯洁与 AlphaGo 的对决
柯洁经历了英雄般的战斗后,依然第二局输给AlphaGo 。
最有价值的信息可能来自AlphaGo之父萨比斯 , 中盘阶段他评论说:“不可思议,根据AlphaGo的评估,柯洁现在下得很完美 。
”赛后萨比斯则评论:“这是一场惊心动魄的令人惊奇的比赛,柯洁几乎把AlphaGo逼到了极限 。
”柯洁今天的最大收获是测出阿法狗的真实水平 。
期望这次比赛能够验证 。
当然它有两个前提条件,一是柯洁把最好水平发挥出来,二是AlphaGo能够经受真正的考验,而不是表面看它只赢一两个子,实际上后台胜率显示根本没有机会 。
前天的第一局,AlphaGo赢了1.5目 。
这是一个很小的差距 , 但柯洁下得谈不上多出色,因为从头到尾他基本没什么机会 。
AlphaGo并不是一个赌徒 , 能赢100目绝不赢99;它是根据胜率估算来行棋的,如果赢1目而它认为胜率是100%,就没必要去下赢100目而胜率只有99%的棋 。
所以,第一局柯洁远远没有逼出AlphaGo的真正实力 。
昨天AlphaGo方面的消息,认为这次虽然只是一个单机版,但棋力已经比去年赢李世石的时候提高了三子 。
这是一个挺吓人的消息 , 因为它会让人类棋手觉得,目前这个版本至少比人类强三子以上 。
老实讲这挺绝望的,三子以上,四子 。
那等于彻底宣布人类棋手跟AlphaGo已经是天壤之别 。
知道,面对一个可以让四子的对手,这是职业和业余的差距,比赛已经失去意义,准确地说那叫戏耍 。
它可以只赢1目甚至半目 , 但不说明任何问题,就像柯洁也可以让只输半目,但那又能说明什么 。
难道会跑大街上喊,快看,柯洁只赢了半目 。
谁都知道,柯洁想怎么赢就怎么赢 , 半目和100目没差别 。
今天的比赛 , 由于“几乎把AlphaGo逼到了极限”,虽然不是让子棋,但基本可以猜出,在人类棋手高水平发挥的前提下,目前AlphaGo让不到人类三子,可能是二子或者略多 。
挂盘讲解的李世石也做出这种判断:AlphaGo并没有提升三子的实力,估计大概有二子 。
至此,本次比赛人类棋手的目标或者说心愿已经达到:测试出AlphaGo的真正实力 。
否则,AlphaGo就永远是上帝般的存在 。
知道它强,但不知道它到底多强,所以它就是上帝 。
知道,没有上帝 。
如果由于无法评测AI(人工智能)的水平,而把它视为上帝一样的存在,这不是人类进化或者说发展的方向 。
等于把命运交给未知,哪怕这个未知是人类创造出来的,也有理由疑虑甚至恐惧 。
所以要感谢柯杰,不愧围棋第一人,他今天的勇气和表现,至少让暂时可以从外部角度了解到AlphaGo的真实水平 。
这是比胜负更重要的事情 。
如何评价AlphaGo
题目:《人工智能》3月15日,举世瞩目的“人机大战”尘埃落定,人工智能“阿尔法狗围棋”(AlphaGo)以4:1的比分战胜人类围棋顶尖高手李世石九段,为世人留下一个不愿接受又不得不接受的事实 。
面对“阿尔法狗围棋”(AlphaGo) , 有人不服 , 如中国的超级围棋新星柯洁九段,就公开向“阿尔法狗围棋”(AlphaGo)叫板:“你赢不了我!”有人叹息:人类智慧最后的尊严在一只“小狗”面前丢失 。
有人甚至悲观地认为 , 机器统治人类的时代即将来临 。
其实,所谓人类尊严、所谓机器人的统治时代,只是我们一些人的臆想,“阿尔法狗围棋”(AlphaGo)的胜利,说到底就是一次技术革命的胜利,是人类对自身的一次超越 。
正如西安交通大学副校长、国家重点基础研究计划(973)“基于视认知的非结构化信息处理基础理论与关键技术”首席科学家徐宗本说的:“任何人工智能技术的成功一定是当代最新技术综合运用的成功,片面说成谁战胜谁是不公平的,也是无意义的,说人类智慧的最后壁垒被攻破,这都是无稽之谈 。
”“阿尔法狗围棋”(AlphaGo)的胜利,背后的最大价值在于,它激励人们持续不断地探索过去人工智能领域一直看似难以实现的人类智能级别 。
从这一点上看,人工智能的胜利也有非凡的意义,甚至可以说具有划时代的意义 。
是的,翻开人类历史 , 哪一次技术革命不带来人类社会翻天覆地的变化?蒸汽机的发明、使用,使人类从农业手工业时代进入了工业社会;电动机的诞生,使人类从工业社会跨入了现代化 。
而以原子能、电子计算机、空间技术和生物工程的发明与应用为主要标志的信息技术革命,更让人类从此进入了自动化、信息化时代 。
每一次技术革命,伴随的都是生产力的发展和人类自身的解放 。
“阿尔法狗围棋”(AlphaGo)的 胜利,是不是会掀起又一次技术革命,我们还需拭目以待 。
然而,人工智能的进步,却可以让我们展望到人类美妙无比的前景 。
我们似乎可以看到 , 不久的将来,到 处都是机器人在人们的指令下为人们服务;我们似乎可以看到 , 那些对于目前医术来说几乎无解的人类大脑和神经疾?。缱员罩ⅰ⒗夏瓿沾糁⒄庋墓室窖?题,随着人工智能的进步 , 一切都会迎刃而解;我们似乎可以看到,有了人工智能的协助,人类真正步入了大同的理想社会 。
是的,“阿尔法狗围棋”(AlphaGo)的胜利 , 是人类的智慧向前迈出的又一步 , 有了这一步,我们的世界将更加美好 。
当然,面对这些进步 , 我们不能只是围观、娱乐和敬仰,我们应该用我们的智慧,去促成人工智能更大的进步!
AlphaGo是什么 谷歌AlphaGo全解读
AlphaGo一般指阿尔法围棋阿尔法围棋(AlphaGo)是第一个击败人类职业围棋选手、第一个战胜围棋世界冠军的人工智能程序 。
其主要工作原理是“深度学习” 。
阿尔法围棋(AlphaGo)是一款围棋人工智能程序 。
其主要工作原理是“深度学习” 。
“深度学习”是指多层的人工神经网络和训练它的方法 。
一层神经网络会把大量矩阵数字作为输入,通过非线性激活方法取权重,再产生另一个数据集合作为输出 。
这就像生物神经大脑的工作机理一样,通过合适的矩阵数量,多层组织链接一起 , 形成神经网络“大脑”进行精准复杂的处理,就像人们识别物体标注图片一样 。
对于最强AlphaGo Zero如何炼成的真心话,都在这里
最强AlphaGo Zero怎样炼成刚刚,Deepmind在Reddit的Machine Learning板块举办了在线答疑活动AMA,Deepmind强化学习组负责人David Silver和其同事热情地回答了网友们提出的各种问题 。
由于在AMA前一天Deepmind刚刚发表了《Mastering the game of Go without human knowledge》(不使用人类知识掌握围棋)的论文,相关的提问和讨论也异常热烈 。
什么是AMA?AMA(Ask Me Anything)是由Reddit的特色栏目 , 你也可以将其理解为在线的“真心话大冒险” 。
AMA一般会约定一个时间,并提前若干天在Reddit上收集问题,回答者统一解答 。
本次Deepmind AMA的回答人是:David Silver:Deepmind强化学习组负责人,AlphaGo首席研究员 。
David Silver1997年毕业于剑桥大学,获得艾迪生威斯利奖 。
David于2004年在阿尔伯塔大学获得计算机博士学位,2013年加盟DeepMind,是AlphaGo项目的主要技术负责人 。
Julian Schritieser:Deepmind高级软件工程师 。
此前有多位机器学习界的大牛/公司在Reddit Machine Learning版块开设AMA,包括:Google Brain Team、OpenAI Research Team 、Andrew Ng and Adam Coates、Jürgen Schmidhuber、Geoffrey Hinton、Michael Jordan 、Yann LeCun、Yoshua Bengio等 。
我们从今天Deepmind的AMA中选取了一些代表性的问题,整理如下:关于论文与技术细节Q: Deepmind Zero的训练为什么如此稳定?深层次的增强学习是不稳定和容易遗忘的 , 自我对局也是不稳定和容易遗忘的,如果没有一个好的基于模仿的初始化状态和历史检查点,二者结合在一起应该是一个灾难...但Zero从零开始,我没有看到论文中有这部分的内容,你们是怎么做到的呢?David Silver:在深层增强学习上,AlphaGo Zero与典型的无模式算法(如策略梯度或者Q学习)采用的是完全不同的算法 。
通过使用AlphaGo搜索,我们可以极大改进策略和自我对局的结果,然后我们会用简单的、基于梯度的更新来训练下一个策略及价值网络 。
比起基于简便的基于梯度的策略改进,这样的做法会更加稳定 。
Q:我注意到ELO等级分增长的数据只与到第40天 , 是否是因为论文截稿的原因?或者说之后AlphaGo的数据不再显著改善?David Silver:AlphaGo已经退役了!这意味着我们将人员和硬件资源转移到其他AI问题中,我们还有很长的路要走呐 。
Q:关于论文的两个问题:Q1:您能解释为什么AlphaGo的残差块输入尺寸为19x19x17吗?我不知道为什么每个对局者需要用8个堆叠的二进制特征层来描述?我觉得1、2个层就够了啊 。
虽然我不是100%理解围棋的规则,但8个层看起来也多了点吧?Q2:由于整个通道使用自我对局与最近的/最好的模型进行比较,你们觉得这对于采用参数空间的特定SGD驱动轨迹对否会有过拟合的风险?David Silver:说起来使用表征可能比现在用的8层堆叠的做法更好!但我们使用堆叠的方式观察历史数据有三个原因:1)它与其他领域的常见输入一致;2)我们需要一些历史状态来表示被KO;3)如果有一些历史数据,我们可以更好地猜测对手最近下的位置,这可以作为一种关注机制(注:在围棋中,这叫“敌之要点即我之要点”),而第17层用于标注我们现在究竟是执黑子还是白子,因为要考虑贴目的关系 。
Q:有了强大的棋类引擎,我们可以给玩家一个评级——例如Elo围棋等级分就是通过棋手对局的分析逐步得出的,那么AlphaGo是否可以对过去有等级分前的棋手的实力进行分析?这可能为研究人类的认知提供一个平台 。
Julian Schritieser:感谢分享,这个主意很棒!我认为在围棋中这完全可以做到,或许可以用最佳应对和实际应对的价值差异或者政策网络给每一手位置评估得到的概率来进行?我有空的时候试一下 。
Q: 既然AlphaGo已经退役了,是否有将其开源的计划?这将对围棋社区和机器学习研究产生巨大的影响 。
还有,Hassabis在乌镇宣称的围棋工具将会什么时候发布?David Silver:现在这个工具正在准备中 。
不久后你就能看到新的消息 。
Q:AlphaGo开发过程中,在系统架构上遇到的最大障碍是什么?David Silver:我们遇到的一个重大挑战是在和李世石比赛的时候,当时我们意识到AlphaGo偶尔会受到我们所谓的“妄想”的影响,也就是说,程序可能会错误理解当前盘面局势 , 并在错误的方向上持续许多步 。
我们尝试了许多方案,包括引入更多的围棋知识或人类元知识来解决这个问题 。
但最终我们取得了成功,从AlphaGo本身解决了这个问题,更多地依靠强化学习的力量来获得更高质量的解决方案 。
围棋爱好者的问题Q:1846年,在十四世本因坊迹目秀策与十一世井上幻庵因硕的一盘对局中,秀策下的第127手让幻庵因硕一时惊急两耳发赤 , 该手成为扭转败局的“耳赤一手” 。
如果是AlphaGo,是否也会下出相同的一首棋?Julian Schritieser:我问了樊麾,他的回答是这样的:当时的围棋不贴目,而AlphaGo的对局中,黑棋需贴7.5目 。
贴目情况不同造成了古今棋局的差异,如果让AlphaGo穿越到当年下那一手,很有可能下的是不同的另一个地方 。
Q:从已发布的AlphaGo相互对局看,执白子的时间更为充裕,因...
AlphaGo这个系统主要由几个部分组成:走棋网络(Policy Neork) , 给定当前局面,预测/采样下一步的走棋 。
快速走子(Fast rollout),目标和1一样,但在适当牺牲走棋质量的条件下,速度要比1快1000倍 。
估值网络(Value Neork) , 给定当前局面 , 估计是白胜还是黑胜 。
蒙特卡罗树搜索(Monte Carlo Tree Search,MCTS) , 把以上这三个部分连起来,形成一个完整的系统 。
我们的DarkForest和AlphaGo同样是用4搭建的系统 。
DarkForest较AlphaGo而言 , 在训练时加强了1 , 而少了2和3,然后以开源软件Pachi的缺省策略 (default policy)部分替代了2的功能 。
以下介绍下各部分 。
1、走棋网络走棋网络把当前局面作为输入,预测/采样下一步的走棋 。
它的预测不只给出最强的一手,而是对棋盘上所有可能的下一着给一个分数 。
棋盘上有361个点,它就给出361个数,好招的分数比坏招要高 。
DarkForest在这部分有创新,通过在训练时预测三步而非一步,提高了策略输出的质量,和他们在使用增强学习进行自我对局后得到的走棋网络(RL neork)的效果相当 。
当然,他们并没有在最后的系统中使用增强学习后的网络,而是用了直接通过训练学习到的网络(SL neork),理由是RL neork输出的走棋缺乏变化,对搜索不利 。
有意思的是在AlphaGo为了速度上的考虑,只用了宽度为192的网络,而并没有使用最好的宽度为384的网络(见图2(a)),所以要是GPU更快一点(或者更多一点),AlphaGo肯定是会变得更强的 。
所谓的0.1秒走一步 , 就是纯粹用这样的网络 , 下出有最高置信度的合法着法 。
这种做法一点也没有做搜索,但是大局观非常强,不会陷入局部战斗中,说它建模了“棋感”一点也没有错 。
我们把DarkForest的走棋网络直接放上KGS就有3d的水平,让所有人都惊叹了下 。
可以说,这一波围棋AI的突破,主要得益于走棋网络的突破 。
这个在以前是不可想像的,以前用的是基于规则,或者基于局部形状再加上简单线性分类器训练的走子生成法 , 需要慢慢调参数年,才有进步 。
当然,只用走棋网络问题也很多,就我们在DarkForest上看到的来说,会不顾大小无谓争劫,会无谓脱先 , 不顾局部死活,对杀出错,等等 。
有点像高手不经认真思考的随手棋 。
因为走棋网络没有价值判断功能,只是凭“直觉”在下棋,只有在加了搜索之后,电脑才有价值判断的能力 。
2、快速走子那有了走棋网络,为什么还要做快速走子呢?有两个原因 , 首先走棋网络的运行速度是比较慢的,AlphaGo说是3毫秒,我们这里也差不多,而快速走子能做到几微秒级别,差了1000倍 。
所以在走棋网络没有返回的时候让CPU不闲着先搜索起来是很重要的,等到网络返回更好的着法后,再更新对应的着法信息 。
其次,快速走子可以用来评估盘面 。
由于天文数字般的可能局面数,围棋的搜索是毫无希望走到底的,搜索到一定程度就要对现有局面做个估分 。
在没有估值网络的时候,不像国象可以通过算棋子的分数来对盘面做比较精确的估值,围棋盘面的估计得要通过模拟走子来进行,从当前盘面一路走到底,不考虑岔路地算出胜负,然后把胜负值作为当前盘面价值的一个估计 。
这里有个需要权衡的地方:在同等时间下,模拟走子的质量高,单次估值精度高但走子速度慢;模拟走子速度快乃至使用随机走子,虽然单次估值精度低,但可以多模拟几次算平均值 , 效果未必不好 。
所以说 , 如果有一个质量高又速度快的走子策略,那对于棋力的提高是非常有帮助的 。
为了达到这个目标,神经网络的模型就显得太慢 , 还是要用传统的局部特征匹配(local pattern matching)加线性回归(logistic regression)的方法,这办法虽然不新但非常好使,几乎所有的广告推荐 , 竞价排名,新闻排序,都是用的它 。
与更为传统的基于规则的方案相比,它在吸纳了众多高手对局之后就具备了用梯度下降法自动调参的能力,所以性能提高起来会更快更省心 。
AlphaGo用这个办法达到了2微秒的走子速度和24.2%的走子准确率 。
24.2%的意思是说它的最好预测和围棋高手的下子有0.242的概率是重合的,相比之下 , 走棋网络在GPU上用2毫秒能达到57%的准确率 。
这里,我们就看到了走子速度和精度的权衡 。
和训练深度学习模型不同 , 快速走子用到了局部特征匹配,自然需要一些围棋的领域知识来选择局部特征 。
对此AlphaGo只提供了局部特征的数目(见Extended Table 4),而没有说明特征的具体细节 。
我最近也实验了他们的办法 , 达到了25.1%的准确率和4-5微秒的走子速度,然而全系统整合下来并没有复现他们的水平 。
我感觉上24.2%并不能完全概括他们快速走子的棋力,因为只要走错关键的一步,局面判断就完全错误了;而图2(b)更能体现他们快速走子对盘面形势估计的精确度,要能达到他们图2(b)这样的水准,比简单地匹配24.2%要做更多的工作,而他们并未在文章中强调这一点 。
在AlphaGo有了快速走子之后,不需要走棋网络和估值网络,不借助任何深度学习和GPU的帮助,不使用增强学习,在单机上就已经达到了3d的水平(见Extended Table 7倒数第二行),这是相当厉害的了 。
任何使用传统方法在单机上达...
转载请注明出处作文大全网 ? alphago是什么语言开发的
GO语言学习系列八——GO函数(func)的声明与使用 GO是编译性语言 , 所以函数的顺序是无关紧要的,为了方便阅读,建议入口函数 main 写在最前面,其余函数按照功能需要进行排列
GO的函数 不支持嵌套,重载和默认参数
GO的函数 支持 无需声明变量,可变长度,多返回值 , 匿名,闭包等
GO的函数用 func 来声明,且左大括号 { 不能另起一行
一个简单的示例:
输出为:
参数:可以传0个或多个值来供自己用
返回:通过用 return来进行返回
【go语言快速排序 go语言map排序】 输出为:
上面就是一个典型的多参数传递与多返回值
对例子的说明:
按值传递:是对某个变量进行复制,不能更改原变量的值
引用传递:相当于按指针传递,可以同时改变原来的值,并且消耗的内存会更少 , 只有4或8个字节的消耗
在上例中,返回值 (d int, e int, f int) { 是进行了命名,如果不想命名可以写成 (int,int,int){ ,返回的结果都是一样的,但要注意:
当返回了多个值,我们某些变量不想要,或实际用不到 , 我们可以使用 _ 来补位,例如上例的返回我们可以写成 d,_,f := test(a,b,c),我们不想要中间的返回值,可以以这种形式来舍弃掉
在参数后面以 变量 ... type 这种形式的,我们就要以判断出这是一个可变长度的参数
输出为:
在上例中,strs ...string 中,strs 的实际值是b,c,d,e,这就是一个最简单的传递可变长度的参数的例子,更多一些演变的形式,都非常类似
在GO中 defer 关键字非常重要,相当于面相对像中的析构函数,也就是在某个函数执行完成后,GO会自动这个;
如果在多层循环中函数里,都定义了 defer ,那么它的执行顺序是先进后出;
当某个函数出现严重错误时,defer 也会被调用
输出为
这是一个最简单的测试了,当然还有更复杂的调用,比如调试程序时,判断是哪个函数出了问题 , 完全可以根据 defer 打印出来的内容来进行判断,非常快速,这种留给你们去实现
一个函数在函数体内自己调用自己我们称之为递归函数,在做递归调用时 , 经常会将内存给占满,这是非常要注意的,常用的比如,快速排序就是用的递归调用
本篇重点介绍了GO函数(func)的声明与使用 , 下一篇将介绍GO的结构 struct
GO短信是什么GO短信加强版是在原GO短信版本上进行全面升级的高级版本,是一款完全免费、界面酷炫、支持气泡式/列表会话界面、支持来信即显弹窗、拥有信息备份/恢复功能、支持安全锁加密/黑名单,支持文件夹管理、拥有丰富个性化设置的android短信应用 。※ 注意: - 测试版用户请*卸载*测试版 , 再安装这个正式版 。- GO短信加强版可以和GO短信同时存在,只需在老版本的“提醒设置“里把“启用通知”和“启动即显短信窗口”关掉;建议同时保存两者一段时间 。- 如果你需要导入GO短信里的设置信息到加强版,只需在“设置“-”GO 短信服务“-”设置信息备份与恢复“中备份(如果你的GO短信没有这些服务,请先更新至GO短信最新版本),然后在GO短信加强版中导入即可 。
- 支持Emoji表情- 支持文件夹管理,里面有收件箱、发件箱、草稿箱和定时信箱,还可以新建加密文件夹,把重要信息复制到文件夹- 手势操作支持,您可以使用左右滑动的手势操作切换“信息”界面和“文件夹”界面- 支持DIY主题,可在选择DIY主题后在“设置—收件箱个性化设置—更换壁纸”进行壁纸设置- 支持多语言独立安装包(设置—应用程序设置—语言选择)- 聊天式会话界面或Android原生风格界面- 支持使用与下载各式主题(设置—界面效果设置—主题选择)- 支持信息即显弹窗显示、快捷回复- 已支持独立于系统短信之外使用- 自带1x1图标widget和4x2中号widget- 支持个性化设置界面- 支持针对不同联系人自定义界面设置- 支持备份/恢复全部或单个联系人信息 , 可以是XML备份格式,还能通过email发送至邮箱保存- 支持设置备份与恢复- 支持安全锁、黑名单功能- 支持手势滑动切换页面(设置—界面效果设置—页面切换设置—切换特效)- 针对CDMA网络自动对长信息进行分割- 支持联系人个性化设置(个性化通知、铃声、签名设置)- 支持对联系人、信息/会话内容删除和设置进行备份操作- 支持时间偏差调整功能- 支持按短信时间排序或按收发顺序排序- 支持快速回复- 支持夜间模式- 支持群发短信- 支持重复提醒功能- 支持隐私模式(隐藏通知栏和即显弹窗提示)- 支持联系人按名字和字母搜索功能、按谷歌和GO短信联系人分组功能- 支持facebook头像显示- 短信息按联系人、按内容搜索功能- 联系人排序、选择、分组、查找功能- 丰富的彩信阅读模式,强大的彩信编辑功能- 免费在线节日短信库
百度创建这是谁七位元老级人物,分别是go语言快速排序:李彦宏,徐勇,刘建国,雷鸣,郭耽,崔姗姗,王啸
以下如果有兴趣,可以go语言快速排序了解一下:
李彦宏,1991年毕业于北京大学信息管理专业,随后赴美国布法罗纽约州立大学完成计算机科学硕士学位 。
在美国go语言快速排序的8年间,李彦宏先生先后担任了道.琼斯公司高级顾问,《华尔街日报》网络版实时金融信息系统设计者,以及在国际知名互联网企业-INFOSEEK资深工程师,是新一代互联网技术领域的权威专家 。他为道.琼斯公司设计的实时金融系统,迄今仍被广泛地应用于华尔街各大公司的网站,其中包括《华尔街日报》的网络版 。
李彦宏最先创建了ESP技术,并将它成功的应用于INFOSEEK/GO.COM的搜索引擎中 。GO.COM的图像搜索引擎是他的另一项极其具有应用价值的技术创新 。
1996年 , 他首先解决了如何将基于网页质量的排序与基于相关性排序完美结合的问题,并因此获得了美国专利go语言快速排序;
1998年,李彦宏先生根据在硅谷工作以及生活的经验,在大陆出版了《硅谷商战》一书,获得了各界的好评;
1999年底 , 携风险投资回国与好友徐勇先生共同创建百度网络技术有限公司;
2001年被评选为“中国十大创业新锐”之一;
2002年荣获首届“IT十大风云人物”称号;
2003年再次荣获“IT十大风云人物”称号;
2004年1月15日,当选第二届“京城十三新锐”;
2004年4月,百度总裁李彦宏当选第二届“中国软件十大杰出青年” 。
徐勇 , 1982年就读北京大学生物系 , 1989年完成生物硕士学位后,获美国洛克菲勒基金会博士奖学金,赴美留学,于美国德州AM大学完成博士学位 , 随后任加州大学伯克利分校博士后 。在美国10年期间 , 徐勇先后任职于两家著名的跨国高新技术公司(QIAGEN, Inc.和Stratagene公司)的高级销售经理,并且获得过杰出销售奖 。1998年 , 徐勇作为制片人之一拍摄了大型专题纪录片《走进硅谷》,客观以及全面的反映硅谷的发展过程,深度探求了硅谷成功背后的种种因素 。在硅谷他多次应邀给来自中国大陆的高级政府官员介绍硅谷的风险投资
机制和创业文化 。1999年,徐勇与他人合作创立Cybercalling.com公司,这个网络电子商务公司在六个月内就实现了赢利 。他与硅谷的众多商业团体都保持着密切的联系, 并为许多新兴的高科技企业提供商业咨询 。1999年底,徐勇与好友李彦宏回国创建了百度 。
刘建国
现任百度公司首席技术官(CTO) 。
1988年本科毕业于西安交通大学计算机科学工程系,1991年硕士毕业于北京大学计算机科学技术系 。1991-2000年 , 在北京大学计算机系任教,1999年被评为副教授 。1997-1998年在美国UIUC计算机科学系做访问学者 。2000年初加盟百度 。主持开发过国内第一个大规模中英文搜索引擎系统(“天网”)、第一个面向消息的中间件产品(“银燕”) 。在软件开发管理、项目管理、部门管理、人员管理等方面有丰富的经验 。现负责公司与技术和工程有关的规则、研究和管理,确保百度在中文搜索服务方面居于世界领先地位 。2006年2月被任命为百度首席技术官 。
2月07日,百度宣布已经正式任命刘建国为公司首席技术官(CTO),此前刘建国为百度技术副总裁 。担任百度CTO后,刘建国除了继续领导技术团队之外,还将致力于增强百度产品市场方面的研究、开发和运营工作,进而推动百度产品的不断创新和用户体验的持续提高 。
据悉,刘建国在软件工程、研究开发领域拥有超过15年的工作经验 。他于2000年1月加入百度 , 并在2000年8月被任命为百度技术副总裁,管理工程师团队,担负研究开发任务 。
加盟百度前,刘建国是北京大学计算机科学技术系的副教授,据悉,他牵头指导了多项国家科学基金会及国家计委支持的研究项目 。任教期间 , 刘建国及他的团队开发出许多大规模的软件产品,其中包括中国最早的中间件产品和中国第一代搜索引擎 。
“6年前建国是百度的第一位员工,他见证了百度成长为国内最大的搜索引擎的全过程 。”百度董事长兼首席执行官李彦宏向采访人员表示,“他领导创建的百度技术团队是中国高科技领域最优秀的技术团队 , 也是世界互联网领域最优秀的技术团队之一 。他所具备的行业知识、技术专长以及卓越的领导才能都是国内首屈一指的 。”
李彦宏表示,刘建国和他带领的团队将扮演关键的角色 , 担负起百度技术创新、产品创新、服务运营的重要责任,以确保百度带给网民最完美的中文搜索体验 。
李彦宏在向百度公司全体员工宣布这一决定时说:“在互联网市场的艰苦岁月中,建国从未动摇过对百度、对自己团队的必胜的信心;在百度扬威国际资本市场的时候,他依然保持冷静的头脑,对团队严格要求 。他领导创建的百度技术团队是中国高科技领域最优秀的技术团队,也是世界互联网领域最优秀的技术团队之一 。六年来,百度的技术团队历经风雨 , 在快速成长中建立了完善的流程,吸引了大批优秀的技术人才,培养了我们自己的骨干力量 。从而奠定了百度中文搜索市场份额绝对第一的基础 。”
刘建国在软件工程、研究开发领域拥有超过15年的工作经验,他有着出色的管理才能和丰富的管理经验 。他于2000年1月加入百度,2000年8月被任命为百度技术副总裁,管理着快速壮大的工程师团队,担负研究开发任务,并且在中文搜索引擎的相关技术领域带来不断创新 。
加盟百度之前,刘建国是北京大学计算机科学技术系的副教授,他牵头指导了多项国家科学基金会及国家计委支持的研究项目 。任教期间,刘建国及他的团队开发出许多大规模的软件产品,其中包括中国最早的中间件产品和中国第一代搜索引擎 。
刘建国本科毕业于西安交通大学计算机科学工程系软件专业,在北京大学获计算机网络方向硕士学位 。1997年至1998年间,他曾作为访问学者在美国伊利诺伊大学厄巴纳-香槟分校(University of Illinois at Urbana-Champaign)计算机科学系进行实时系统、计算机网络、分布式系统等方向的研究 。
刘建国个人简历:
刘建国先生,中国著名的搜索引擎专家,原任北京大学计算机系副教授和计算机网络和分布式系统研究室副主任,现任百度公司首席技术官,中国计算机学会教育工作委员会委员,中国互联网协会理事,中关村专业人士协会项目管理分会委员 。
刘建国 1988年毕业于西安交通大学计算机科学工程系软件专业,1991年进入北京大学计算机科学技术系软件专业主攻计算机网络方向,获得硕士学位后留校进行科研教学工作 。其间,参与北京大学校园网的规划和建设;在国家自然科学基金委员会重点项目"多媒体、多功能、多语言电子邮件系统"的研制项目中负责"多功能 "部分的设计和开发,实现了X.400电子邮件系统和传真电信系统的互通以及符合LDAP、DIXIE协议的轻量级目录访问子系统;在"开放系统通信平台 -银燕网络支持系统"项目中任技术负责人,所开发的产品-银燕网络支持系统是国内第一款中间件软件产品 , 已成功地运行于多家企事业单位;主持开发了贵州省建行储蓄通存通兑系统;1995年至1997年负责国家重点95攻关项目"大型中英文信息发现系统"的研制开发,作为技术负责人主持开发著名的"天网"中英文搜索引擎 。1997-1998在美国University of Illinois at Urbana-Champaign计算机科学系做访问学者,在该系的Real-time Systems Laboratory进行实时系统方面的研究 。
刘建国在国内外著名学术杂志和报纸上发表文章十余篇,参与编著学术著作两部 。先后获得过中国建设银行计算机应用科技进步奖、广东省金融系统计算机应用科技进步奖一等奖、北京大学第三届自然科学研究成果一等奖、北京大学宝洁优秀教师奖、北京大学教学优秀奖、北京大学"安泰"优秀青年教师奖 。
刘建国1995年即开始中文搜索引擎相关技术的研究和产品开发,为此领域全球最早开拓者之一 。在搜索引擎涉及的诸多技术领域有广泛的知识,尤其在信息检索、计算机网络技术、分布式系统、高性能计算、中文信息处理、大规模系统构建与运行等方面有深刻的见解和独到的创新 。同时,刘建国在技术管理、团队管理、产品管理、技术商业应用等方面有较高的造诣和丰富的经验 。在他的带领下 , 百度技术部已成为国内技术能力最强的团队之一,为百度成为全球最大的中文搜索引擎并在产业中居于霸主地位做出了杰出的贡献 。
后人为了表示对这七位创造了百度神化的元老尊为”百度七剑”
彻底理解Golang Map 本文目录如下,阅读本文后,将一网打尽下面Golang Map相关面试题
Go中的map是一个指针,占用8个字节 , 指向hmap结构体;源码 src/runtime/map.go 中可以看到map的底层结构
每个map的底层结构是hmap,hmap包含若干个结构为bmap的bucket数组 。每个bucket底层都采用链表结构 。接下来,我们来详细看下map的结构
bmap就是我们常说的“桶”,一个桶里面会最多装 8 个 key,这些 key 之所以会落入同一个桶 , 是因为它们经过哈希计算后 , 哈希结果是“一类”的,关于key的定位我们在map的查询和插入中详细说明 。在桶内,又会根据 key 计算出来的 hash 值的高 8 位来决定 key 到底落入桶内的哪个位置(一个桶内最多有8个位置) 。
bucket内存数据结构可视化如下:
注意到 key 和 value 是各自放在一起的,并不是key/value/key/value/...这样的形式 。源码里说明这样的好处是在某些情况下可以省略掉 padding字段 , 节省内存空间 。
当 map 的 key 和 value 都不是指针 , 并且 size 都小于 128 字节的情况下,会把 bmap 标记为不含指针 , 这样可以避免 gc 时扫描整个 hmap 。但是,我们看 bmap 其实有一个 overflow 的字段,是指针类型的,破坏了 bmap 不含指针的设想,这时会把 overflow 移动到 extra 字段来 。
map是个指针,底层指向hmap,所以是个引用类型
golang 有三个常用的高级类型 slice 、map、channel,它们都是 引用类型,当引用类型作为函数参数时,可能会修改原内容数据 。
golang 中没有引用传递,只有值和指针传递 。所以 map 作为函数实参传递时本质上也是值传递,只不过因为 map 底层数据结构是通过指针指向实际的元素存储空间,在被调函数中修改 map,对调用者同样可见 , 所以 map 作为函数实参传递时表现出了引用传递的效果 。
因此,传递 map 时,如果想修改map的内容而不是map本身,函数形参无需使用指针
map底层数据结构是通过指针指向实际的元素 存储空间,这种情况下,对其中一个map的更改,会影响到其他map
map 在没有被修改的情况下,使用 range 多次遍历 map 时输出的 key 和 value 的顺序可能不同 。这是 Go 语言的设计者们有意为之,在每次 range 时的顺序被随机化,旨在提示开发者们 , Go 底层实现并不保证 map 遍历顺序稳定,请大家不要依赖 range 遍历结果顺序 。
map 本身是无序的,且遍历时顺序还会被随机化,如果想顺序遍历 map,需要对 map key 先排序,再按照 key 的顺序遍历 map 。
map默认是并发不安全的,原因如下:
Go 官方在经过了长时间的讨论后 , 认为 Go map 更应适配典型使用场景(不需要从多个 goroutine 中进行安全访问) , 而不是为了小部分情况(并发访问),导致大部分程序付出加锁代价(性能),决定了不支持 。
场景:2个协程同时读和写,以下程序会出现致命错误:fatal error: concurrent map writes
如果想实现map线程安全,有两种方式:
方式一:使用读写锁mapsync.RWMutex
方式二:使用golang提供的sync.Map
sync.map是用读写分离实现的,其思想是空间换时间 。和map RWLock的实现方式相比,它做了一些优化:可以无锁访问read map,而且会优先操作read map,倘若只操作read map就可以满足要求(增删改查遍历),那就不用去操作write map(它的读写都要加锁),所以在某些特定场景中它发生锁竞争的频率会远远小于map RWLock的实现方式 。
golang中map是一个kv对集合 。底层使用hash table,用链表来解决冲突 ,出现冲突时,不是每一个key都申请一个结构通过链表串起来,而是以bmap为最小粒度挂载,一个bmap可以放8个kv 。在哈希函数的选择上,会在程序启动时,检测 cpu 是否支持 aes,如果支持,则使用 aes hash,否则使用 memhash 。
map有3钟初始化方式,一般通过make方式创建
map的创建通过生成汇编码可以知道,make创建map时调用的底层函数是 runtime.makemap。如果你的map初始容量小于等于8会发现走的是 runtime.fastrand 是因为容量小于8时不需要生成多个桶,一个桶的容量就可以满足
makemap函数会通过fastrand创建一个随机的哈希种子,然后根据传入的hint计算出需要的最小需要的桶的数量,最后再使用makeBucketArray 创建用于保存桶的数组,这个方法其实就是根据传入的B计算出的需要创建的桶数量在内存中分配一片连续的空间用于存储数据,在创建桶的过程中还会额外创建一些用于保存溢出数据的桶,数量是2^(B-4)个 。初始化完成返回hmap指针 。
找到一个 B,使得 map 的装载因子在正常范围内
Go 语言中读取 map 有两种语法:带 comma 和 不带 comma 。当要查询的 key 不在 map 里,带 comma 的用法会返回一个 bool 型变量提示 key 是否在 map 中;而不带 comma 的语句则会返回一个 value 类型的零值 。如果 value 是 int 型就会返回 0,如果 value 是 string 类型,就会返回空字符串 。
map的查找通过生成汇编码可以知道,根据 key 的不同类型,编译器会将查找函数用更具体的函数替换,以优化效率:
函数首先会检查 map 的标志位 flags 。如果 flags 的写标志位此时被置 1 了,说明有其他协程在执行“写”操作,进而导致程序 panic 。这也说明了 map 对协程是不安全的 。
key经过哈希函数计算后,得到的哈希值如下(主流64位机下共 64 个 bit 位):
m: 桶的个数
从buckets 通过 hashm 得到对应的bucket,如果bucket正在扩容,并且没有扩容完成,则从oldbuckets得到对应的bucket
计算hash所在桶编号:
用上一步哈希值最后的 5 个 bit 位,也就是01010,值为 10,也就是 10 号桶(范围是0~31号桶)
计算hash所在的槽位:
用上一步哈希值哈希值的高8个bit 位,也就是 10010111 ,转化为十进制,也就是151,在 10 号 bucket 中寻找** tophash 值(HOB hash)为 151* 的 槽位**,即为key所在位置,找到了 2 号槽位,这样整个查找过程就结束了 。
如果在 bucket 中没找到,并且 overflow 不为空,还要继续去 overflow bucket 中寻找,直到找到或是所有的 key 槽位都找遍了,包括所有的 overflow bucket 。
通过上面找到了对应的槽位,这里我们再详细分析下key/value值是如何获取的:
bucket 里 key 的起始地址就是 unsafe.Pointer(b) dataOffset 。第 i 个 key 的地址就要在此基础上跨过 i 个 key 的大?。欢颐怯种溃瑅alue 的地址是在所有 key 之后,因此第 i 个 value 的地址还需要加上所有 key 的偏移 。
通过汇编语言可以看到,向 map 中插入或者修改 key,最终调用的是mapassign函数 。
实际上插入或修改 key 的语法是一样的,只不过前者操作的 key 在 map 中不存在,而后者操作的 key 存在 map 中 。
mapassign 有一个系列的函数,根据 key 类型的不同,编译器会将其优化为相应的“快速函数” 。
我们只用研究最一般的赋值函数mapassign。
map的赋值会附带着map的扩容和迁移,map的扩容只是将底层数组扩大了一倍,并没有进行数据的转移 , 数据的转移是在扩容后逐步进行的,在迁移的过程中每进行一次赋值(access或者delete)会至少做一次迁移工作 。
1.判断map是否为nil
每一次进行赋值/删除操作时,只要oldbuckets != nil 则认为正在扩容,会做一次迁移工作,下面会详细说下迁移过程
根据上面查找过程 , 查找key所在位置 , 如果找到则更新,没找到则找空位插入即可
经过前面迭代寻找动作,若没有找到可插入的位置,意味着需要扩容进行插入,下面会详细说下扩容过程
通过汇编语言可以看到,向 map 中删除 key , 最终调用的是mapdelete函数
删除的逻辑相对比较简单,大多函数在赋值操作中已经用到过,核心还是找到 key 的具体位置 。寻找过程都是类似的,在 bucket 中挨个 cell 寻找 。找到对应位置后 , 对 key 或者 value 进行“清零”操作 , 将 count 值减 1 , 将对应位置的 tophash 值置成Empty
再来说触发 map 扩容的时机:在向 map 插入新 key 的时候 , 会进行条件检测,符合下面这 2 个条件 , 就会触发扩容:
1、装载因子超过阈值
源码里定义的阈值是 6.5 (loadFactorNum/loadFactorDen),是经过测试后取出的一个比较合理的因子
我们知道,每个 bucket 有 8 个空位,在没有溢出,且所有的桶都装满了的情况下 , 装载因子算出来的结果是 8 。因此当装载因子超过 6.5 时,表明很多 bucket 都快要装满了,查找效率和插入效率都变低了 。在这个时候进行扩容是有必要的 。
对于条件 1 , 元素太多,而 bucket 数量太少,很简单:将 B 加 1,bucket 最大数量( 2^B )直接变成原来 bucket 数量的 2 倍 。于是,就有新老 bucket 了 。注意,这时候元素都在老 bucket 里,还没迁移到新的 bucket 来 。新 bucket 只是最大数量变为原来最大数量的 2 倍( 2^B * 2 )。
2、overflow 的 bucket 数量过多
在装载因子比较小的情况下,这时候 map 的查找和插入效率也很低,而第 1 点识别不出来这种情况 。表面现象就是计算装载因子的分子比较小,即 map 里元素总数少,但是 bucket 数量多(真实分配的 bucket 数量多,包括大量的 overflow bucket)
不难想像造成这种情况的原因:不停地插入、删除元素 。先插入很多元素,导致创建了很多 bucket,但是装载因子达不到第 1 点的临界值,未触发扩容来缓解这种情况 。之后,删除元素降低元素总数量,再插入很多元素 , 导致创建很多的 overflow bucket , 但就是不会触发第 1 点的规定,你能拿我怎么办?overflow bucket 数量太多,导致 key 会很分散,查找插入效率低得吓人,因此出台第 2 点规定 。这就像是一座空城,房子很多,但是住户很少,都分散了,找起人来很困难
对于条件 2 , 其实元素没那么多,但是 overflow bucket 数特别多,说明很多 bucket 都没装满 。解决办法就是开辟一个新 bucket 空间,将老 bucket 中的元素移动到新 bucket,使得同一个 bucket 中的 key 排列地更紧密 。这样,原来,在 overflow bucket 中的 key 可以移动到 bucket 中来 。结果是节省空间,提高 bucket 利用率,map 的查找和插入效率自然就会提升 。
由于 map 扩容需要将原有的 key/value 重新搬迁到新的内存地址 , 如果有大量的 key/value 需要搬迁,会非常影响性能 。因此 Go map 的扩容采取了一种称为“渐进式”的方式 , 原有的 key 并不会一次性搬迁完毕,每次最多只会搬迁 2 个 bucket 。
上面说的hashGrow()函数实际上并没有真正地“搬迁”,它只是分配好了新的 buckets,并将老的 buckets 挂到了 oldbuckets 字段上 。真正搬迁 buckets 的动作在growWork()函数中,而调用growWork()函数的动作是在 mapassign 和 mapdelete 函数中 。也就是插入或修改、删除 key 的时候,都会尝试进行搬迁 buckets 的工作 。先检查 oldbuckets 是否搬迁完毕,具体来说就是检查 oldbuckets 是否为 nil 。
如果未迁移完毕,赋值/删除的时候,扩容完毕后(预分配内存),不会马上就进行迁移 。而是采取 增量扩容 的方式 , 当有访问到具体 bukcet 时 , 才会逐渐的进行迁移(将 oldbucket 迁移到 bucket)
nevacuate 标识的是当前的进度,如果都搬迁完,应该和2^B的长度是一样的
在evacuate 方法实现是把这个位置对应的bucket,以及其冲突链上的数据都转移到新的buckets上 。
转移的判断直接通过tophash 就可以 , 判断tophash中第一个hash值即可
遍历的过程,就是按顺序遍历 bucket,同时按顺序遍历 bucket 中的 key 。
map遍历是无序的 , 如果想实现有序遍历,可以先对key进行排序
为什么遍历 map 是无序的?
如果发生过迁移 , key 的位置发生了重大的变化,有些 key 飞上高枝,有些 key 则原地不动 。这样,遍历 map 的结果就不可能按原来的顺序了 。
如果就一个写死的 map , 不会向 map 进行插入删除的操作 , 按理说每次遍历这样的 map 都会返回一个固定顺序的 key/value 序列吧 。但是 Go 杜绝了这种做法,因为这样会给新手程序员带来误解,以为这是一定会发生的事情,在某些情况下,可能会酿成大错 。
Go 做得更绝,当我们在遍历 map 时,并不是固定地从 0 号 bucket 开始遍历,每次都是从一个**随机值序号的 bucket开始遍历,并且是从这个 bucket 的一个 随机序号的 cell **开始遍历 。这样 , 即使你是一个写死的 map,仅仅只是遍历它,也不太可能会返回一个固定序列的 key/value 对了 。
归并排序归并排序 (Merge sortgo语言快速排序,或mergesort),是创建在归并操作上的一种有效的排序算法,效率为。1945 年由约翰·冯·诺伊曼首次提出 。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行 。
这里面提到go语言快速排序了两个概念,分别是 分治(法) 和 递归,它们是什么呢?
分治法(Divide and Conquer)是基于多路分支递归求和的一种很重要的算法范式 。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题,直到最后子问题可以简单的直接求解,原问题的解就是子问题的解的合并 。这个技巧是很多高效算法的基础,如排序算法中的快速排序和归并排序 , 傅立叶变换中的快速傅立叶变换…
分治模式在每层递归时都有三个步骤:
递归(英语:Recursion),又译为递回,在数学和计算机科学中,递归指由一种(或多种)简单的基本情况定义的一类对象或方法,并规定其他所有情况都能被还原为其基本情况 , 如函数的定义中使用函数自身的方法 。递归一词还较常用于描述以自相似方法重复事物的过程 。例如,当两面镜子相互之间近似平行时,镜中嵌套的图像是以无限递归的形式出现的 。也可以理解为自go语言快速排序我复制的过程 。
归并排序算法完全遵循分治模式,直观上,其操作步骤如下:
当待排序的序列长度为 1 时,递归“开始回升”,在这种情况下无须作任何工作,因为长度为 1 的每个序列都已排好序 。
MERGE 的详细工作过程如下:
我们必须证明第 12~17 行 for 循环的第一次迭代之前该循环不变式成立,且在该循环的每次迭代时保持该不变式,当循环终止时,该不变式须提供一种有用的性质来证明算法的正确性 。
前面我们分析了分治算法的过程,我们可以把 MERGE 作为归并排序算法中的一个子程序来用 。
上面已经对分治法做了正确性证明,归并排序的正确性不言而喻 。
分治算法运行时间的递归式来自基本模式的三个步骤 , 即分解、解决和合并 。假设 T(n) 是规模为 n 的一个问题的运行时间 。若问题规模足够?。缍阅掣龀A?c,n≤c,则直接求解需要常量时间,可以将其写成 O(1) 。假设把原问题分解成 a 个子问题,每个子问题的规模是原问题的 1/b 。为了求解一个规模为 n/b 的子问题,需要 T(n/b) 的时间,所以需要 aT(n/b) 的时间来求解 a 个子问题 。如果分解问题成子问题需要时间 D(n) , 合并子问题的解成原问题的解需要时间 C(n),那么得到递归式:
现在我们来讨论归并排序 。假定问题规模是 2 的幂(不是 2 的幂时也能正确地工作),归并排序一个元素的时间是常量 , 当有 n1 个元素时,分解运行的时间如下:
为了分析归并排序,我们可以将 D(n) 与 C(n) 相加,即把一个函数与另一个函数相加,得到的和是一个 n 的线性函数,即。把它与来自“解决”步骤的项 2T(n/2) 相加,将给出归并排序的最坏情况的运行时间
将递归式重写,得到
其中,常量 c 代表求解规模为 1 的问题所需要的时间以及在分解步骤与合并步骤处理每个数组元素所需要的时间 。(相同的常量一般不可能刚好即代表求解规模为 1 的问题的时间又代表分解步骤与合并步骤处理每个数组元素的时间 。通过假设 c 为这两个时间的较大者并认为我们的递归式将给出运行时间的一个上界 , 或者通过假设 c 为这两个时间的较小者并认为我们的递归式将给出运行时间的下界 , 我们可以暂时回避这个问题 。两个界的阶都是,合在一起将给出运行时间为) 。
求解递归式的过程如下图所示:
可以看出,树根 cn 通过递归分解,直到规模降为 1 后,每个子问题只要代价 c 。分解步骤一共经历了次,即树高为层,每层的代价为 cn,因此总代价为。
上面我们已经知道了,总代价为,忽略低阶项和常量 c,归并排序的时间复杂度为 O(nlogn) 。
归并排序的合并函数,在合并两个有序数组为一个有序数组时,需要借助额外的存储空间,但是这个申请额外的内存空间,会在合并完成之后释放 , 因此,在任意时刻,只会有一个临时的内存空间在使用 , 临时内存空间最大也不会超过 n 个数据的大小,所以空间复杂度是 O(n) 。
Javascript 递归版
Go
迭代版
递归版
go语言快速排序的介绍就聊到这里吧,感谢你花时间阅读本站内容 , 更多关于go语言map排序、go语言快速排序的信息别忘了在本站进行查找喔 。

    推荐阅读