数据结构与算法入门
来源:互联网 发布:试卷出题软件 编辑:程序博客网 时间:2024/05/16 09:57
任何高大上的技术都需要踏踏实实的基础:算法+数据结构+编译原理+操作系统
白板编程
To summarize: We have seen that computer programming is an art, because it applies accumulated knowledge to the world, because it requires skill and ingenuity, and especially because it produces objects of beauty.
搜索引擎:搜索算法+排序算法
算法的力量:性能优化
计算机科学有两类根本问题。一类是理论:算法,数据结构,复杂度,机器学习,模式识别,等等等。一类是系统:操作系统,网络系统,分布式系统,存储系统,游戏引擎,等等等等。理论走的是深度,是在追问在给定的计算能力约束下如何把一个问题解决得更快更好。而系统走的是广度,是在追问对于一个现实的需求如何在众多的技术中设计出最多快好省的技术组合。
- 谷歌搜索,0.67s得到结果,上亿的数据;
- 苹果siri:语音识别,理解人类语言并智能回应;
- 推荐算法:机器学习;
- 动画的渲染,运动效果,图形学
- 游戏,迷宫的生成,扫雷:洪水填充(Flood fill)算法
- 无人机,计算机视觉,识别图像信息
- 线性排序-树形结构-图形结构
- 数据结构很重要
- 斐波那契堆,线段树,网络流
To summarize: We have seen that computer programming is an art, because it applies accumulated knowledge to the world, because it requires skill and ingenuity, and especially because it produces objects of beauty.
选择排序(Selection Sort)
简单,但是对于任何数组,选择排序两层循环必须完全完成。
插入排序(Insertion Sort)
对于插入循环来说,,提前终止内层循环是一个很重要的性质 。 对于越有序的数组进行排序,时间复杂度会从O(N^2)向O(N)无限接近
冒泡排序(Bubble Sort)(
Bubble Sort (没有插入性能好)
var n = [28,34,54,43];for(var j = 0 ; j < n.length - 1;j++){ for(var i = 0;i < n.length- 1 - j;i++){ if(n[i]>n[i+1]){ var temp = n[i]; n[i] = n[i+1]; n[i+1] = temp; } } console.log(n); }
插入排序升级,希尔排序(Shell Sort)n二分之三次方
Merge Sort 归并排序(本质:递归)
把数组分成一半,左边的进行排序(分成一半……),右边的进行排序(分成一半……),
最后,会分到一定的程度,每一部分只有一个元素(本身就是有序的)。
然后归并.
二分法,一层层分级,分为3级,8/2=4/2=2/2=1,log(N)层级,
如果归并过程以O(n)的复杂度来解决的话,那么N log(N)
解决问题:以O(n)的算法来归并,形成新的有序的数组
思路:开辟同样大小的临时空间,不过有利有弊,算法的速度提升了,但是需要的内存空间增加了。(在计算机,时间的效率比空间的效率重要的多)
使用三个索引在内存上追踪
蓝色:表示归并过程中最终需要归并的位置
红1,红2:分别指向两个已经排好序的数组
比较1和2哪个小,先进入归并数组,1进入,然后蓝箭头位移一位,比较2和4
k表示i和j比较后下一个需要放置的位置(在程序中始终满足变量的定义是程序的基础)
l(left) r(right)前闭后闭的空间,
快速排序(Quick Sort) 20世纪最伟大的算法之一
以一个元素为基点,然后移动到其大于之前元素的位置上。(核心:Partitions)
如果e>v,直接融入v,如果e<v,j+1位置元素和e互换位置,然后j++(橙色块增加),I++(紫块增加)
当我们遍历完后,再进行l和j互换位置,最终:
退化至O(n^2)的算法,当两端极端不平衡
升级
堆排序(Heap Sort)
优先队列(Priority Queue)
比如:操作系统把CPU的执行周期划成时间片(一个时间片只能执行一个任务),每个任务都有一个优先级。所以,需要动态选择优先级最高的任务执行
优先队列主要操作:入队,出队(取出优先级最高的元素)
二叉堆(Binary Heap)
因为完全二叉树的特性(左边的子节点是父节点的二倍),所以我们可以使用数组来存储二叉堆
从堆中添加元素(Shift Up)
新添加元素依次和父元素比较,如果比父元素大则交换位置
从堆中取出元素(Shift Down)
最后一个元素和取出元素替换,count–
最后一个元素依次和左右两个子元素比较(取最大值替换),逐层比较,直到终止
Heapify
叶子节点的父节点和两个叶子对比,然后最大的成为父节点,向上一层一层的比较
Selection Sort(从小到大):
1.:在选择范围选择出最小的元素,然后和第一位互换位置
2.:在剩下的位置中找出最小的元素
依此类推
只能计算int型
#include <iostream> #include <algorithm> #include <string> using namespace std; void selectionSort(int arr[], int n){ for(int i = 0 ; i < n ; i ++){ // 寻找[i, n)区间里的最小值 int minIndex = i; for( int j = i + 1 ; j < n ; j ++ ) if( arr[j] < arr[minIndex] ) minIndex = j; //交换位置 swap( arr[i] , arr[minIndex] ); } } int main() { int a[10] = {10,9,8,7,6,5,4,3,2,1}; selectionSort(a,10); for( int i = 0 ; i < 10 ; i ++ ) cout<<arr[i]<<" "; cout<<endl; return 0;
####升级:浮点数,字符串,自定义(利用模板来解决)#include <iostream> #include "Student.h" using namespace std; template<typename T> void selectionSort(T arr[], int n){ for(int i = 0 ; i < n ; i ++){ int minIndex = i; for( int j = i + 1 ; j < n ; j ++ ) if( arr[j] < arr[minIndex] ) minIndex = j; swap( arr[i] , arr[minIndex] ); } } int main() { // 测试模板函数,传入整型数组 int a[10] = {10,9,8,7,6,5,4,3,2,1}; selectionSort( a , 10 ); for( int i = 0 ; i < 10 ; i ++ ) cout<<a[i]<<" "; cout<<endl; // 测试模板函数,传入浮点数数组 float b[4] = {4.4,3.3,2.2,1.1}; selectionSort(b,4); for( int i = 0 ; i < 4 ; i ++ ) cout<<b[i]<<" "; cout<<endl; // 测试模板函数,传入字符串数组 string c[4] = {"D","C","B","A"}; selectionSort(c,4); for( int i = 0 ; i < 4 ; i ++ ) cout<<c[i]<<" "; cout<<endl; // 测试模板函数,传入自定义结构体Student数组 Student d[4] = { {"D",90} , {"C",100} , {"B",95} , {"A",95} }; selectionSort(d,4); for( int i = 0 ; i < 4 ; i ++ ) cout<<d[i]; cout<<endl; return 0; }
运算符进行重载:C++预定义中的运算符的操作对象只局限于基本的内置数据类型,但是对于我们自定义的类型(类)是没有办法操作的。
运算符重载的实质就是函数重载或函数多态。运算符重载是一种形式的C++多态。目的在于让人能够用同名的函数来完成不同的基本操作。
运算符重载为类的成员函数的一般语法形式为:
函数类型 operator 运算符(形参表)
{
函数体;
}
运算符重载为类的友元函数的一般语法形式为:
friend 函数类型 operator 运算符(形参表)
{
函数体;
}
//解决.h文件的多重引用问题,.h文件不对外隐藏 #ifndef INC_02_SELECTION_SORT_USING_TEMPLATE_STUDENT_H #define INC_02_SELECTION_SORT_USING_TEMPLATE_STUDENT_H #include <iostream> #include <string> //容易出现命名空间污染的问题 using namespace std; struct Student{ string name; int score; //运算符重载 bool operator<(const Student& otherStudent){ return score != otherStudent.score ? score > otherStudent.score : name < otherStudent.name; } friend ostream& operator<<(ostream &os, const Student &student){ os<<"Student: "<<student.name<<" "<<student.score<<endl; return os; } }; #endif //INC_02_SELECTION_SORT_USING_TEMPLATE_STUDENT_H
- 数据结构与算法入门
- 数据结构与算法入门
- 算法基础:数据结构与算法入门概览
- 各种数据结构与算法知识入门经典
- 数据结构与算法导论之入门简介
- 《数据结构与算法》学习之入门篇
- 数据结构与算法学习-哈希表入门
- 数据结构与算法从入门到懵逼 - 链表
- 数据结构与算法入门(1)--基本概念
- 数据结构与算法 基础概述 入门必备!
- 优秀博客推荐:各种数据结构与算法知识入门经典
- 各种数据结构与算法知识入门经典(不断更新)
- 算法与数据结构,从入门到不放弃~
- 数据结构与算法(Python)-python快速入门篇1
- 数据结构与算法(Python)-Python快速入门篇2
- 数据结构与算法(Python)-Python快速入门篇3
- 数据结构与算法(Python)-Python快速入门篇4
- 数据结构与算法学习笔记——基础入门
- (转)对冲基金之王科恩,天才还是魔鬼?——读《黑色优势》有感
- mybatis SQL性能调优
- 前端Sass回顾以及Compass入门小记
- 算法导论学习之分治法
- HDU
- 数据结构与算法入门
- C++学习笔记之——友元
- 打造网络营销利器-第3篇--站内链接-网站优化进阶
- 用C++实现的完全二叉树,实现前序遍历,中序遍历,后序遍历。
- Java程序规范
- 每天一个Linux命令(1):ls命令
- 在mybatis执行SQL语句之前进行拦击处理
- 精读前后端渲染之争
- Java的内部类和匿名内部类