数据结构
稀疏数组(sparsearray)
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
- 记录数据一共有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
1 | func main(){ |
队列(queue)
- 队列是一个有序列表,可以用数组或者链表实现
- 遵循先入先出的原则
数组模拟队列
- 创建一个数组array作为队列的一个字段
- front初始化为-1
- rear表示队列尾部,初始化为-1
- 要把数组作为一个环形队列
1 | type CircleQueue struct { |
链表(link)
单向链表
为了比较好的对单链表进行增删改查的操作,一般都会设置一个头节点,头节点的作用主要是用来标识链表头,本身这个节点不存放数据
1 | //定义节点 |
双向链表
单向链表只能从一个方向查找,单向链表不能自我删除,要依靠辅助节点
解决方法:引入双向链表
1 | //定义节点 |
单向环形列表
1 | type UserNode struct { |
约瑟夫问题
N个人围成一圈,从第一个开始报数,第M个将出列,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,出列的顺序是:5,4,6,2,3。
解决方法:利用一个不带头节点的循环链表来处理约瑟夫问题
1 | type Boy struct { |
排序
选择排序
选择排序属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,经过和其他元素重整,再依原则交换位置后达到排序的目的。
1 | func SelectSort(arr *[10]int) { |
插入排序
插入排序输入内部排序法,是对于欲排序的元素以插入的方式找寻该元素的适当位置,以达到排序的目的。
把N个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含N-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码一次与有序表元素的排序码进行比较,插入适当的位置。
1 | func InsertSort(arr []int){ |
快速排序
快速排序是对冒泡排序的一种改进,基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程都可以递归进行,以此达到整个数据变成有序序列。
1 | func QuickSort(left ,right int ,arr []int) { |
排序算法的比对
排序方法 | 时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | O(n2) | O(n2) | O(n) | O(1) | 稳定 |
选择排序 | O(n2) | O(n2) | O(n2) | O(1) | 不稳定 |
插入排序 | O(n2) | O(n2) | O(n) | O(1) | 稳定 |
希尔排序 | O(n1.3) | O(n2) | O(n) | O(1) | 不稳定 |
快速排序 | O(nlog2n) | O(n2) | O(nlog2n) | O(nlog2n) | 不稳定 |
归并排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(n) | 稳定 |
堆排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(1) | 不稳定 |
基数排序 | O(n∗k) | O(n∗k) | O(n∗k) | O(n+k) | 稳定 |
栈
栈是一个先入后出的有序列表(队列是先入先出)
1 | type Stack struct { |
递归
迷宫问题
1 | func SetWay(maze *[8][7]int ,i ,j int) bool { |
哈希表(散列)
哈希表是根据关键码值直接进行访问的数据结构,通过把关键码映射到表中的一个位置来访问记录,以加快查找的速度,这个映射函数叫做散列函数,存放记录的数据叫做哈希表(散列表)
1 | //使用链表实现哈希表,该链表不带表头 |