数据结构和算法

数据结构和算法(一):复杂度、数组、链表、栈、队列

2019-11-21  本文已影响0人  冰风v落叶

从广义上来讲:数据结构就是一组数据的存储结构 , 算法就是操作数据的方法

数据结构是为算法服务的,算法是要作用在特定的数据结构上的。

10个最常用的数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie树

10个最常用的算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法

本文总结了20个最常用的数据结构和算法,不管是应付面试还是工作需要,只要集中精力攻克这20个知识点就足够了。

数据结构和算法(一):复杂度、数组、链表、栈、队列的传送门

数据结构和算法(二):递归、排序、通用排序算法的传送门

数据结构和算法(三):二分查找、跳表、散列表、哈希算法的传送门

数据结构和算法(四):二叉树、红黑树、递归树、堆和堆排序、堆的应用的传送门

数据结构和算法(五):图、深度优先搜索和广度优先搜索、字符串匹配算法、Trie树、AC自动机的传送门

数据结构和算法(六):贪心算法、分治算法、回溯算法、动态规划、拓扑排序的传送门

第一章 复杂度

一、什么是复杂度分析?
二、为什么要进行复杂度分析?
三、如何进行复杂度分析?
四、常用的复杂度级别?
五、如何掌握好复杂度分析方法?

复杂度分析关键在于多练,所谓孰能生巧。

第二章 数组

数组看起来很简单,但是很多人没有理解数组的精髓。为什么数组要从0开始编号,而不是从1开始呢? 带着这个问题,开始学习。

一、数组如何实现随机访问的?
数组中 i 元素的地址 = 首地址 + i * 每个元素的大小 (如果数组中存放的是Int类型的,那么data_type_size就是4个字节)

a[i]_address = base_address + i * data_type_size
二、 数组的插入和删除
三、 那么数组的下标为什么从0开始呢?
下标从0开始,则a[k]的内存地址为:
a[k]_address = base_address + k * type_size

下标从1开始,则a[k]的内存地址为:
a[k]_address = base_address + (k - 1) * type_size

第三章 链表

一、 链表是什么
二、 链表的插入、删除、访问
链表的插入和删除
三、 链表与数组的对比
数组与链表的对比
四、 如何基于链表实现LRU缓存淘汰算法?
五、 字符串用单向链表存储,如果判断此字符串是一个回文串呢?(例如:level 返过来也是 level)
六、 练习题

精选了5个常见的链表操作,你只要把这5个练熟,我保证你以后再也不会害怕写链表的代码了。

第四章 栈

一、 什么是栈
// 一个用数组实现的简单顺序栈
public class ArrayStack{
    var stack: Array = Array<Any>()
    // 入栈
    func push(element: Any){
        stack.append(element)
    }
    // 出栈
    func pop() -> Any?{
        guard stack.count > 0 else{ return nil }
        let lastElement = stack.last
        stack.removeLast()
        return lastElement
    }
}
二、 经典使用场景 - 系统调用栈
int main() {
   int a = 1; 
   int ret = 0;
   int res = 0;
   ret = add(3, 5);
   res = a + ret;
   printf("%d", res);
   reuturn 0;
}

int add(int x, int y) {
   int sum = 0;
   sum = x + y;
   return sum;
}

上述代码的函数调用栈,如下图所示:


函数调用栈-示例
三、 经典使用场景 - 表达式求值 - 也就是如何计算:A*B+C-D/E ?
四、 经典使用场景 - 如何实现浏览器的前进、后退功能

第五章 队列

一、什么是队列
栈和队列
二、 队列的插入和删除
顺序队列的数据搬移
三、循环队列
四、阻塞队列和并发队列
多个消费者应对一个生产者
五、课后题:写出循环队列代码
上一篇 下一篇

猜你喜欢

热点阅读