算法章节 数组、链表、栈、队列

200 阅读4分钟

数组

概念与特性

1,数组是线性表,用一组连续的内存空间存储⼀组具有相同类型的数据

2,最大的特性是⽀持按照下标O(1)时间复杂度内快速访问数组元素

3,⼀维数组寻址公式:a[i]_addr = base_addr + i * data_type_size

操作与复杂度

1. 随机访问时间复杂度是O(1);
2. 在数组中间任意位置插⼊数据的时间复杂度是O(n);

3. 删除数组中任意位置数据的时间复杂度是O(n)

应⽤场景

数组是其他数据结构和算法的实现基础,⽐如栈、队列、堆、⼆分查找等

其他知识点

1. 数组需要连续的内存空间,对内存的要求较⾼;
2. 数组中的数据连续存储,对CPU缓存友好;
3. ⼤部分编程语⾔中,数组下标都是从0开始编号;
4. ⼤部分编程语⾔中,都提供了容器类型以⽀持动态数组(动态扩容);
5. 编程语⾔中的数组类型并不等同于数据结构中讲的数组;

掌握程度

能够⾃⼰动⼿实现⼀个动态数组类

链表

概念与特性

1. 链表是线性表,不需要连续的内存空间来存储元素,通过指针将串联每个链表中的结点;
2. 常⽤的链表结构有:单链表、双向链表、循环链表,其中双向链表因为⽀持在O(1)时间复杂度内找到前驱结点,在实际开发中最常⽤;

操作与复杂度

1. 与数组对⽐,查找第i个元素的时间复杂度是O(n);

2. 在已知前驱结点的情况下,单链表中插⼊数据的时间复杂度是O(1);
3. 在已知前驱结点的情况下,单链表中删除数据的时间复杂度是O(1);
注意:上⾯的插⼊、删除操作,都是针对已知前驱结点的情况,如果未知前驱结点,在单链表中插⼊、删除数据时间复杂度是O(n),⽽在双向链表 中插⼊、删除数据的时间复杂度仍然是O(1)。这也是双向链表⽐单链表更常⽤的主要原因。

应⽤场景

链表是其他数据结构和算法的实现基础,⽐如跳表、散列表等

其他知识点

1. 链表中的数据不连续存储,对CPU缓存不友好;
2. 在实际的编程中,可定义有头链表,也可以定义⽆头链表;有头链表指的是链表中的头结点不存储数据;

掌握程度

1. 熟练实现单链表、双向链表、循环链表的定义和操作

2. 熟练实现经典的链表题⽬,⽐如反转链表、链表求中间结点、合并有序链表、删除链表倒数第K个结点等;

概念与特性

1. 栈是⼀种操作受限的线性表,只能在⼀端插⼊删除数据;
2. 栈的最⼤特性是先进后出;

操作与复杂度

1. ⼊栈操作,在栈顶放⼊数据,时间复杂度是O(1);
2. 出栈操作,从栈顶取出数据,时间复杂度是O(1);

应⽤场景

1. 函数调⽤栈;
2. 编译器利⽤栈来实现表达式求值;
3. 浏览器中的前进后退功能的实现也会⽤到栈;

其他知识点

1. 栈既可以⽤数组来实现,也可以⽤链表来实现;
2. 基于数组实现的⽀持动态扩容的栈的插⼊操作的均摊时间复杂度是O(1);

掌握程度

1. 熟练利⽤数组实现⼀个栈;
2. 熟练利⽤链表实现⼀个栈;
3. 掌握基于数组实现的⽀持动态扩容的栈的插⼊操作的时间复杂度分析;
4. ⽤栈检查括号是否匹配,⽐如:{[()]()[{}]}或[{()}([])]等都为合法格式,⽽{[}()]或[({)]为不合法的格式;

队列

概念与特性

1. 队列是⼀种操作受限的线性表,只能在两端插⼊、删除数据;
2. 队列的最⼤特性是先进先出;

操作与复杂度

1. ⼊队操作,在队尾插⼊数据,时间复杂度是O(1);
2. 出队操作,从队头取出数据,时间复杂度是O(1);

应⽤场景

队列常⽤在有限资源池中,⽤于排队请求,⽐如数据库连接池等;

其他知识点

1. 队列既可以⽤数组来实现,也可以⽤链表来实现;
2. 最常使⽤的队列是基于数组实现的循环队列;

掌握程度

熟练实现⼀个循环队列,重点是掌握队列的判空和判满条件;