冒泡排序 冒泡排序是大多数人学的第一种排序算法,在面试中,也是问的最多的一种,有时候还要求手写排序代码,因为比较简单. 冒泡排序属于交换类的排序算法. 一.算法介绍 现在有一堆乱序的数,比如:5 9 1 6 8 14 6 49 25 4 6 3. 第一轮迭代:从第一个数开始,依次比较相邻的两个数,如果前面一个数比后面一个数大,那么交换位置,直到处理到最后一个数,最后的这个数是最大的. 第二轮迭代:因为最后一个数已经是最大了,现在重复第一轮迭代的操作,但是只处理到倒数第二个数. 第三轮迭代:因为最…
快速排序 快速排序是一种分治策略的排序算法,是由英国计算机科学家Tony Hoare发明的, 该算法被发布在1961年的Communications of the ACM 国际计算机学会月刊. 注:ACM = Association for Computing Machinery,国际计算机学会,世界性的计算机从业员专业组织,创立于1947年,是世界上第一个科学性及教育性计算机学会. 快速排序是对冒泡排序的一种改进,也属于交换类的排序算法. 一.算法介绍 快速排序通过一趟排序将要排序的数据分割成…
排序算法 人类的发展中,我们学会了计数,比如知道小明今天打猎的兔子的数量是多少.另外一方面,我们也需要判断,今天哪个人打猎打得多,我们需要比较. 所以,排序这个很自然的需求就出来了.比如小明打了5只兔子,小王打了8只,还有部落其他一百多个人也打了.我们要论功行赏,谁打得多,谁就奖赏大一点. 如何排序呢,怎么在最快的时间内,找到打兔子最多的人呢,这是一个很朴素的问题. 经过很多年的研究,出现了很多的排序算法,有快的有慢的.比如: 插入类排序有:直接插入排序和希尔排序 选择类排序有:直接选择排序和堆…
选择排序 选择排序,一般我们指的是简单选择排序,也可以叫直接选择排序,它不像冒泡排序一样相邻地交换元素,而是通过选择最小的元素,每轮迭代只需交换一次.虽然交换次数比冒泡少很多,但效率和冒泡排序一样的糟糕. 选择排序属于选择类排序算法. 我打扑克牌的时候,会习惯性地从左到右扫描,然后将最小的牌放在最左边,然后从第二张牌开始继续从左到右扫描第二小的牌,放在最小的牌右边,以此反复.选择排序和我玩扑克时的排序特别相似. 一.算法介绍 现在有一堆乱序的数,比如:5 9 1 6 8 14 6 49 25 4…
插入排序 插入排序,一般我们指的是简单插入排序,也可以叫直接插入排序.就是说,每次把一个数插到已经排好序的数列里面形成新的排好序的数列,以此反复. 插入排序属于插入类排序算法. 除了我以外,有些人打扑克时习惯从第二张牌开始,和第一张牌比较,第二张牌如果比第一张牌小那么插入到第一张牌前面,这样前两张牌都排好序了,接着从第三张牌开始,将它插入到已排好序的前两张牌里,形成三张排好序的牌,后面第四张牌继续插入到前面已排好序的三张牌里,直至排序完. 一.算法介绍 举个简单例子,插入排序一个 4 个元素的数…
希尔排序 1959 年一个叫Donald L. Shell (March 1, 1924 – November 2, 2015)的美国人在Communications of the ACM 国际计算机学会月刊发布了一个排序算法,从此名为希尔排序的算法诞生了. 注:ACM = Association for Computing Machinery,国际计算机学会,世界性的计算机从业员专业组织,创立于1947年,是世界上第一个科学性及教育性计算机学会. 希尔排序是直接插入排序的改进版本.因为直接插入…
归并排序 归并排序是一种分治策略的排序算法.它是一种比较特殊的排序算法,通过递归地先使每个子序列有序,再将两个有序的序列进行合并成一个有序的序列. 归并排序首先由著名的现代计算机之父John_von_Neumann在1945年发明,被用在了EDVAC(一台美国早期电子计算机),足足用墨水写了 23 页的排序程序.注:冯·诺依曼(John von Neumann,1903年12月28日-1957年2月8日),美籍匈牙利数学家.计算机科学家.物理学家,是20世纪最重要的数学家之一. 一.算法介绍 我…
优先队列及堆排序 堆排序(Heap Sort)由威尔士-加拿大计算机科学家J. W. J. Williams在1964年发明,它利用了二叉堆(A binary heap)的性质实现了排序,并证明了二叉堆数据结构的可用性.同年,美国籍计算机科学家R. W. Floyd在其树排序研究的基础上,发布了一个改进的更好的原地排序的堆排序版本. 堆排序属于选择类排序算法. 一.优先队列 优先队列是一种能完成以下任务的队列:插入一个数值,取出最小或最大的数值(获取数值,并且删除). 优先队列可以用二叉树来实现…
哈希表:散列查找 一.线性查找 我们要通过一个键key来查找相应的值value.有一种最简单的方式,就是将键值对存放在链表里,然后遍历链表来查找是否存在key,存在则更新键对应的值,不存在则将键值对链接到链表上. 这种链表查找,最坏的时间复杂度为:O(n),因为可能遍历到链表最后也没找到. 二.散列查找 有一种算法叫散列查找,也称哈希查找,是一种空间换时间的查找算法,依赖的数据结构称为哈希表或散列表:HashTable. Hash: 翻译为散列,哈希,主要指压缩映射,它将一个比较大的域空间映射到…
二叉查找树 二叉查找树,又叫二叉排序树,二叉搜索树,是一种有特定规则的二叉树,定义如下: 它是一颗二叉树,或者是空树. 左子树所有节点的值都小于它的根节点,右子树所有节点的值都大于它的根节点. 左右子树也是一颗二叉查找树. 二叉查找树的特点是,一直往左儿子往下找左儿子,可以找到最小的元素,一直往右儿子找右儿子,可以找到最大的元素. 看起来,我们可以用它来实现元素排序,可是我们却使用了二叉堆来实现了堆排序,因为二叉查找树不保证是一个平衡的二叉树,最坏情况下二叉查找树会退化成一个链表,也就是所有节点…
AVL树 二叉查找树的树高度影响了查找的效率,需要尽量减小树的高度,AVL树正是这样的树. 一.AVL树介绍 AVL树是一棵严格自平衡的二叉查找树,1962年,发明者Adelson-Velsky和Landis发表了论文,以两个作者的名字命名了该数据结构,这是较早发明的平衡二叉树. 定义如下: 首先它是一棵二叉查找树. 任意一个节点的左右子树最大高度差为1. 由于树特征定义,我们可以计算出其高度h的上界h<=1.44log(n),也就是最坏情况下,树的高度约等于1.44log(n). 假设高度h的…
某些教程不区分普通红黑树和左倾红黑树的区别,直接将左倾红黑树拿来教学,并且称其为红黑树,因为左倾红黑树与普通的红黑树相比,实现起来较为简单,容易教学.在这里,我们区分开左倾红黑树和普通红黑树. 红黑树是一种近似平衡的二叉查找树,从2-3树或2-3-4树衍生而来.通过对二叉树节点进行染色,染色为红或黑节点,来模仿2-3树或2-3-4树的3节点和4节点,从而让树的高度减小.2-3-4树对照实现的红黑树是普通的红黑树,而2-3树对照实现的红黑树是一种变种,称为左倾红黑树,其更容易实现. 使用平衡树数据…
关于数据结构等的学习,以及学习算法的感想感悟,听了郝斌老师的数据结构课程,其中他也提到了学习数据结构的或者算法的一些个人见解,我觉的很好,对我的帮助也是很大,算法本就是令人头疼的问题,因为自己并没有学习过算法的系统性的课程,现在还是处于不断摸索的阶段,好多算法题目根本就没有什么思路,导致自己对好多题目都很是头疼,就算是自己做过的一些算法的题目,再次遇到也还是不一定会做出来,他给出的建议就是,看懂别人的程序,然后自己去敲,一定会出错,然后调试,有错误接着调试,一直到没有错误为止,并且要时常的去复习…
之前已经介绍过冒泡排序算法和简单选择排序算法和原理,现在有Js实现. 冒泡排序算法 let dat=[5, 8, 10, 3, 2, 18, 17, 9]; function bubbleSort(data) { for(let i=0;i<data.length-1;i++){ for(let j=0;j<data.length-1-i;j++){ if(data[j]>data[j+1]){ [data[j],data[j+1]]=[data[j+1],data[j]]; } } }…
文章首发于 阅读更友好的GitBook. 2-3-4树和普通红黑树 某些教程不区分普通红黑树和左倾红黑树的区别,直接将左倾红黑树拿来教学,并且称其为红黑树,因为左倾红黑树与普通的红黑树相比,实现起来较为简单,容易教学.在这里,我们区分开左倾红黑树和普通红黑树. 红黑树是一种近似平衡的二叉查找树,从2-3树或2-3-4树衍生而来.通过对二叉树节点进行染色,染色为红或黑节点,来模仿2-3树或2-3-4树的3节点和4节点,从而让树的高度减小.2-3-4树对照实现的红黑树是普通的红黑树,而2-3树对照实…
今天我们要介绍的是一种特殊的二叉树--二叉搜索树,同时我们也会讲到一种排序算法--二叉树排序算法.这两者之间有什么联系呢,我们一起来看一下吧. 开始之前呢,我们先来介绍一下如何创建一颗二叉搜索树. 假设我们有这样一些数据:[9,5,2,1,4,2,1,41,22,11,35,24,11,10,4,23,9,45,2,35,12,35,16,27,56,31,73] 我们就用这些数据来创建二叉排序树. 首先,我们将第一个数据9作为二叉排序树的根节点, 然后我们拿到第二个数据5,现在我们要进行判断,…
一.Dijkstra最短路径算法 是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 实现一 // // Dijkstra // ACM // Find the number of minimal path // // Created by Rachel on 18-2-12. // Copyright (c) 2014年 ZJU. All rights reserved. // #include <io…
在网上搜索算法的博客,发现一个比较悲剧的现象非常普遍: 原理讲不清,混乱 啰嗦 图和文对不上 不可用,甚至代码还出错 我总结一个清晰不罗嗦版: 原理: 从数组头元素索引i开始,寻找后面最小的值(比i位置值小),进行交换: 索引i依次+1 选择排序时间复杂度选择排序的时间复杂度是O(N2).假设被排序的数列中有N个数.遍历一趟的时间复杂度是O(N),需要遍历多少次呢?N-1!因此,选择排序的时间复杂度是O(N2). 选择排序稳定性选择排序是稳定的算法,它满足稳定算法的定义.算法稳定性 -- 假设在…
主函数package main import ( "fmt" "math/rand" "sort" "time") const ( num = 10000 // 测试数组的长度 rangeNum = 100000 // 数组元素大小范围)func main() { arr := GenerateRand()//生成随机数组 //排序前 复制原数组 org_arr := make([]int, num) copy(org_arr…
1. 冒泡排序算法实现 package main import "fmt" func main() { values := []int{3, 98, 55, 46, 22, 3, 9, 18} fmt.Println(values) BubbleSortAsc(values) BubbleSortDesc(values) } func BubbleSortAsc(values []int) { for x := 0; x < len(values)-1; x++ { for y…
选择.插入排序 main.cpp 1 #include <iostream> 3 #include "SortTestHelper.h" 4 5 using namespace std; 6 7 template<typename T> 8 void selectionSort(T arr[],int n){ 9 for(int i = 0 ; i < n ; i ++){ 10 int minIndex = i; 11 for( int j = i +…
基本思想 直接选择排序是从无序区选一个最小的元素直接放到有序区的最后. 初始状态:无序区为a[1...n],有序区为空. 第一次排序:在无序区a[1...n]中选出最小的记录a[k],将它与有序区的第一个元素交换,使a[1...1]和a[2...n]分别变为 记录个数增加1个的新有序区和记录个数减少1个的新无序区. ... 经过n-1次排序结束. 算法实现 public void sort(int[] array) { for (int i = 0; i < array.length; i++)…
——参考自<算法图解> 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): newArr = [] for i in range(le…
归并排序采取了分治的思想,每次分别排左半边和右半边,不断递归调用自己,直到只有一个元素递归结束,开始回溯,调用merge函数,合并两个有序序列,再合并的时候每次给末尾追上一个最大int这样就不怕最后一位的数字不会被排序. #include <bits/stdc++.h> using namespace std; void merge(int a[],int n,int left ,int mid,int right); void merge_sort(int a[],int n,int lef…
数据结构和算法在计算机科学里,有非常重要的地位.此系列文章尝试使用 Golang 编程语言来实现各种数据结构和算法,并且适当进行算法分析. 我们会先简单学习一下Golang,然后进入计算机程序世界的第一个大门. 简单入门Golang 我们只学Golang语言的一个子集,足以开展接下来数据结构和算法的实现即可. 一.前言 Golang语言是谷歌Google公司在2007年启动,并在2009年正式发布并开源的高级编程语言.开源地址:https://github.com/golang/go,官网地址:…
包.变量和函数 一.举个例子 现在我们来建立一个完整的程序main.go: // Golang程序入口的包名必须为 main package main // import "golang" // 导入其他地方的包,包通过 go mod 机制寻找 import ( "fmt" "golang/diy" ) // init函数在main函数之前执行 func init() { // 声明并初始化三个值 var i, j, k = 1, 2, 3 //…
流程控制语句 计算机编程语言中,流程控制语句很重要,可以让机器知道什么时候做什么事,做几次.主要有条件和循环语句. Golang只有一种循环:for,只有一种判断:if,还有一种特殊的switch条件选择语句. 一.条件语句 举个例子: // 判断语句 if a > 0 { fmt.Println("a>0") } else { fmt.Println("a<=0") } 当a > 0时打印a>0,否则打印a<=0.其中条件a &…
结构体和方法 一.值,指针和引用 我们现在有一段程序: package main import "fmt" func main() { // a,b 是一个值 a := 5 b := 6 fmt.Println("a的值:", a) // 指针变量 c 存储的是变量 a 的内存地址 c := &a fmt.Println("a的内存地址:", c) // 指针变量不允许直接赋值,需要使用 * 获取引用 //c = 4 // 将指针变量 c…
接口 在Golang世界中,有一种叫interface的东西,很是神奇. 一.数据类型 interface{} 如果你事前并不知道变量是哪种数据类型,不知道它是整数还是字符串,但是你还是想要使用它. Golang就产生了名为interface{}的数据类型,表示并不知道它是什么类型.举例子: package main import ( "fmt" "reflect" ) func print(i interface{}) { fmt.Println(i) } fun…
并发.协程和信道 Golang语言提供了go关键字,以及名为chan的数据类型,以及一些标准库的并发锁等,我们将会简单介绍一下并发的一些概念,然后学习这些Golang特征知识. 一.并发介绍 我们写程序时,可能会读取一个几千兆的日志,读磁盘可能需要读几十秒钟,我们不可能一直等他,因为虽然磁盘IO繁忙,但是处理器CPU很空闲,我们可以并发地开另一条路去处理其他逻辑. 在操作系统层面,出现了多进程和多线程的概念.一个处理器会在一个时间片里比如20纳秒执行一个进程,当时间片用完了或者发生了中断比如进程…