算法:是在好的数据结构的基础上的。比较,交换
概念:
1. 算法的复杂度:1.时间复杂度 。2.空间复杂度(越来越不重要了,因为空间越来越不值钱了)
2.时间复杂度:即算法所话费的时间。1.平均运行的时间 2.最佳 和 最差 的运行情况 (依据这2两点)
3.典型的表示法:Big O 表示法(大O):N表示数据的个数。 ----》 复杂度越低,运行效率则越高。
4.搜索: 1. 线性搜索: O(N),每个都要遍历一遍 2. 二叉搜索: O(log N),可以不用每一个都遍历到。
排序: 1.冒泡排序: O(N^2) ,2个2个比较,大的/小的 则交换位置往上一直冒泡,
2.插入排序: O(N^2) 外层循环从i=1下标开始,内层循环则从i-1,开始,倒序着与i比较,往0下标方向比较,知道不符合条件的才落位,否则一直存在与临时变量中
3.顺序排序: O(N^2) 即 用临时变量把第一次遍历的最大/最小值的下标记住,然后和首交换位置即可。每一次的遍历都会找出最大或者最小的值出来,然后换位。
4.快速排序:(二分排序:类似于:二叉排序)O(NlogN),每个至少遍历一次,但是 不是所有的都遍历2次,所以O(NlogN)
核心思想:1. 找出 分界值 ,用其他的数据和他进行比较,进行左右分组 2.递归思想
作业:把数组,使用二分法排序:从中间1分为2.
2.#include <algorithm>C++算法文件 记忆方法: al go ri th m ====》 哦 勾 睿 思 M(口诀哦)all go ri th m
排序:(交换位置)
1.冒泡排序法 -----》 关键:2个2个进行的比较
2个2个进行比较,1元素和2元素比较,之后交换和2和3元素比较,之后交换和3和4元素比较,for(int i=0;i<size;i++) { bool f=false; for(j=0;j<size-1-i;j++) {
if(arr[j] > arr[j+1]){ f=true;swap(arr[j],arr[j+1]); } if(!f) break; } }
乱序数组: 【3】【6】【1】【8】【20】【2】【10】
第一次排: 【3】【6】。。。 【3】【1】【6】。。。。 【3】【1】【6】【8】。。。 【3】【1】【6】【8】【20】。。
【3】【1】【6】【8】【2】【20】。。。 【3】【1】【6】【8】【2】【10】【20】。。。
此时最大的数20已经排到位了:第二此循环就可以不用管20了,第二次又从下标0开始冒泡,冒到end-1,第三次冒到end-2,第N次,冒到end-i;
2.快速排序法(二分排序法) 类似于 二叉树 -----》关键:递归与分界下标的返回。兔子j,乌龟++i 赛跑,裁判index(交换) 左边集合数, 右边集合数
记住3大函数:1. 主执行函数 sort() 2. 执行递归函数 sortIn(int begin ,int end) 3. 进行分组和排序的函数 divies(int begin ,in end)
1. sort(){ sortIn(0,size-1); } 2. sortIn(int p,int r){ if(p>r)return; int index=divies(p,r); sortIn(p,index-1); sortIn(index+1, r ) ; }
3. divies(int p,int r){ int index= rand()%(r-p+1)+p; swap(arr[index],arr[r]); int i=p-1; for(int j=p; j<r; j++){ if(arr[j] > arr[r]) { ++i; swap(arr[j] , arr[i]); } } swap(arr[++i],arr[r]) ; return i }
1.一堆数中找个随机数作为分界数:2 7 8 9 6 3 5 34 ------》随机出9 ------》 交换9与34的位置 --》 2 7 8 34 6 3 5 9--》从2遍历到5,每个值和9比较,9用来作为比较值
如果>9,就龟+1 ,然后让该元素和龟元素交换值。 然后在把9放到龟+1那个位置,因为龟位置是左边数据组,右边是大数据组,9和龟+1,这样的话,就把9给了龟,交换的元素到了尾巴后面,但也仍然是 兔子的数据。 再返回9的位置所在作为分界值(下一次遍历的终点,起点) 外层函数得到其返回值之后,就递归二次1. paixu(begin,index-1) 2. paixu(index+1,end);
3. 插入排序法 ----》 关键:第二个循环是倒序滴,第一个循环从1开始滴,比较的数让他放入临时变量中,一个一个往前比(交换位置即可)。
1.第一个循环 和第二个循环 相对是 ==》 反向的哦,第二个循环以第一个循环i值作为:j=i-1 i>=0&& arr [ j ] >tmp;i--
for(int i=1;i<size;i++){
int tmp=arr[i]; int j; bool f=false;
for(j=i-1 , j > =0 && arr[ j ] > tmp; j--){
arr[j+1] = arr[ j] ; f=true; // [2][7]}[9][4][3][8][5][1][0][6] 9>4 9->4 7>4 7->9 2<4 4->7 只是向前进一步而已,不要arr[i]=arr[j];
} if( f) arr[ j+1 ]=tmp;
}
乱序数组:【3】【6】【1】【8】【20】【2】【10】
第一次排:外层for从下标1开始的,因为二层for是根据外层for i值来进行反序比较排列的(放入临时变量中)
【3】【6】 第二次:【1】【3】【6】第三次:【1】【3】【6】【8】第四次:【1】【3】【6】【8】【20】。。。。。。。
4.选择排序 :--》 关键:内部循环遍历一次,经过比较之后,记住最大/小的小标值,然后和大循环里面的下标值进行替换罢了。
注意:要用这个不断改变的下标来比较哦。别用死的i来比较哦。
数据结构:核心,通过*&的返回|操作,来达到各种效果(且:是上一层的指针成员的返回,并不是本体的返回)
常用的数据结构:数组,链表,栈(先进后出一个出口),队列(2个口,一个出一个进,先进先出),树:二叉树搜索:
概念:数据与数据之间的关系(逻辑,存储),与数据类型无关
1.顺序:数组 2.链式:单链表,双链表,树 3.哈希存储:根据节点关键字直接计算出该节点的位置(如同加密解密)hash
2.链表的优势:伸缩性大。
3.树的优势:结合了排序数组 和 链表伸缩性的双优势。先左再根再右 或者 先右再根再左 2种搜索顺序。其他的回乱哦。
4.list的灵魂函数: *& getNOdePtr(), 其他的函数大部分都是基础该函数进行的操作。
好的记住:冒泡,插入,选择,
1.冒泡:每一次把一个极值排到最后面【end】下标。
2.插入:每一次都把i下标 之前的元素的大小排好,i下标之后 的元素先不管。内层的循环就从i---0,来倒序这,比较,i元素就由临时变量存放。
3.选择:每一次都把一个极值排到最前面【0】下标。
4.