• 《算法十二》(个人笔记)


    个人算法笔记:

    STL:标准模板库
    Standard Template Library
    
    	STL概述:
    		序列式容器:数据无序
    			vector数组
    			list双向链表
    			deque双向动态队列
    		关系式容器:数据有序
    			map 
    			set
    			multimap
    			multiset
    		
    		容器都有的功能:增删改查
    		容器都有的函数:
    			构造、析构、插入、删除
    			查找、拷贝构造、元素个数......
    		
    		迭代器:返回地址
    			迭代器:用来定位容器中某个元素
    					数组:下标
    					链表:next指针
    					容器:智能指针
    					
    			迭代器返回值:是容器中元素的地址
    						  因此每次使用最好初始化begin()
    			
    			迭代器.begin():指向第一个元素的地址
    			迭代器.end():指向最后一个元素的后面
    			容器.insert(迭代器, 数据):插入
    			如果容器发生改变,迭代器会失效
    			
    		List:双向动态链表
    		
    		数组&&链表:数组查找高效
    					链表插入删除高效
    					数组连续,链表不连续
    		
    		deque:双向动态队列
    			   介于数组和链表之间
    	
    	排序算法:shell排序/基数排序/桶排序
    		shell排序:
    			1.优化后的插入排序
    			2.按步长step分组:步长一开始设置为元素个数/2
    			3.组内插入排序
    			4.步长=步长/2
    			
    		基数排序:
    			1.创建临时数组
    			2.初始化临时数组
    			3.临时数组排序
    			4.将临时数组值赋值回原数组
    			5.delete临时数组
    			限制:1.不能有重复运算
    				  2.空间浪费大
    			优点:不需要经过比较
    
    		桶排序:基数排序的升级
    			1.根据数据范围获取排序次数
    			2.制作桶并且初始化
    			3.遍历a数组并且按照排序依据将a数组元素存到桶里
    			4.放回原来数组里
    		总结:希尔排序速度快,不稳定
    			  桶排序速度快,稳定,但是空间复杂度高
    		
    		
    		分治:分而治之
    		二分查找:折半查找
    		归并排序:两个有序数组合并为一个有序数组
    		
    		归并排序:
    			递归的拆分+合并
    			合并:
    				1.准备临时数组
    				2.将数据元素依序放到临时数组中
    				3.将数据元素从临时数组拷贝回到原数组中,释放临时数组
    				
    		二分查找:有序数组按照二分方式来查找数据
    			递归方法:int mid = l + (r-l)/2;//中间 
    					  if(l==r) return -1;//没有找到的情况,此时l==r 
    					  if(finddata==a[mid]) return mid;
    					  if(finddata>a[mid]) half_find(a, mid+1, r, finddata);
    					  if(finddata<a[mid]) half_find(a, l, mid, finddata);
    					  
    			非递归方法:int mid;
    						int left = l;
    						int right = r;
    						while(left < right){
    							mid = left + (right-left)/2;
    							if(finddata == a[mid]) return mid;
    							if(finddata > a[mid]){
    								left = mid+1;
    							}else{
    								right = mid;
    							}
    						}
    						return -1;//没有找到的情况,此时left==right 
    		
    			递归练习之汉诺塔问题:
    				if(num<1) return;//num不符合实际的情况 
    				han_nuo(num-1, A, C, B);
    				printf("%c-->%c 
    ", A, C);
    				han_nuo(num-1, B, A, C);
    			
    			二分查找与归并排序总结:
    				都是分治思想
    				二分:每次排除一半
    				归并:拆分成为2个,递归的进行拆分直到都成为有序数组
    					  然后合并有序数组————>排序成功
    				
    		
    		N叉树:
    			一棵树有多个分叉
    			森林:多棵树
    			节点:树中的元素,子树
    			枝干,叶子节点,路径长度
    			层:根节点到某些结点的路径长度相同,同一层
    			
    			N叉树的增删改查
    			
    		
    		有序二叉树:
    			二叉树:每个节点有且只有2个孩子
    			有序二叉树:左孩子<根<右孩子
    			叶子节点:没有孩子的节点
    			
    		
    		
    		寻路算法:
    		1.深度寻路算法:
    			二维地图:二维数组
    				二维数组上标识特定数值作为地图上对象	
    			
    			应用于RGB游戏中比较广泛
    			缺点:1.二维地图,只可以走直线
    				  2.不一定能找到最佳路径
    				  
    		
    		2.广度寻路算法:
    			遍历整个地图中所有可以走的点
    			并且将其存入到一颗四叉树里
    			之后从起点开始搜索这棵树查找终点即可
    		
    		小总结:
    			深度寻路:
    				有回退	循环少   适用于宽阔大地图   不一定能找到最短路径
    			广度寻路:
    				没有回退  循环多   适用与小地图     一定能找到最短路径
    			但是都只能走直线
    			
    		3.A星寻路:
    			结构:N叉树
    			直线代价斜线代价:符合勾股定理
    			代价:每走一步,距离终点所付出的
    			 f = g + h + w;
    			 f : 当前点到终点的代价
    			 g : 起点到当前点的代价
    			 h : 当前点到终点的预估代价(只计算直线距离,并忽略障碍)
    			 w : 权重  路:   平地    上坡路  丘陵  沼泽   坑 
    			
    		
    	动态规划:
    		使用动态规划:重叠子问题
    		最优值,最佳解
    		斐波那契数列问题
    		
    	背包问题:
    		当背包重量==0:什么也不能偷
    		B(i, j):i代表还有几件商品可以偷
    				j代表还剩下的背包空间是多少
    		
    
    
    机试准备:
      1.setfill/setw使用
      float f1 = 2.99;
      float f2 = 8.9099;
      int i = 10;
      cout << setfill('*');
      //setw是设置域宽,就是输出数据所占几列
      //如果在默认的情况下,输出的数据不能达到所规定的域宽就用空格填充
      //setfill是设置填充物
      //使用操纵符时,需要包含头文件iomanip
      cout << setw(10) << f1 << endl;
      cout << setw(10) << f2 << endl;
      cout << setw(10) << i << endl;
     
      2.定义结构体
      struct Student{
          int id;
          char name[20];
      };
      可以使用typedef添加别名
      typedef struct Student{
          int id;
          char name[20];
      }Student;
     
      使用:Student s; 
     
      3.关于字符串读取
      string str = "hello gy";
      int i = 0;
      while(str[i] != ''){
          cout << str[i] << endl;
          i++;
      }
     
      4.排序问题
      复试不要求一般用:冒泡排序
      int len = 6;
      int num[] = {5,2,77,1,99,66};
      for(int i=0; i<len-1; i++){
          for(int j=0; j<len-1-i; j++){
              if( num[j]>num[j+1] ){
                  int temp = num[j];
                  num[j] = num[j+1];
                  num[j+1] = temp;
              }
          }
      }
      for(int i=0; i<len; i++){
          cout << num[i] << " ";
      }
     
      5.数字和字符之间转换
          例如:将字符'7'转为数字7
          char a = '7';
          int a_num = a - '0';
          例如:将数字 5 转换成字符'5'
          int b_num = 5;
          char b = b_num + '0';
     
      6.进制转化:10进制转8进制
      int num = 666;
      int result[100];
      int len = 0;
      while(num/8 != 0){
          result[len] = num%8;
          len++;
          num /= 8;
      }
      result[len] = num;
      for(int i=len; i>=0; i--){
          cout << result[i] <<endl;
      }
     
      7.质数判断
      int num = 10;
      int temp = sqrt(num);
      bool isZhiShu = true;//默认是质数
      for(int i=2; i<=temp; i++){
          if( num%i==0 ){
              isZhiShu = false;//不是质数
              break;
          }  
      }
      if(isZhiShu){
          cout << "是质数" << endl; 
      }else{
          cout << "不是质数" << endl;
      }
     
      8.字符串拷贝函数strcpy
      char *strcpy(char *dest, const char *src);
      将参数 src 字符串拷贝至参数 dest 所指的地址
      char string[10];
      char *str1 = "abcdefgh";
      //将str1的内容拷贝给string数组
      strcpy(string, str1);
      printf("%s
    ", string);
     
      9.字符串拼接函数strcat
      char *strcat(char *dest, const char *src);
      作用:返回dest字符串起始地址,并且dest = dest+src
      char str[20];
      char* str1 = "gyy";
      char* str2 = "wgg";
      strcat(str, str1);
      strcat(str, str2);
      printf("%s
    ", str);
     
      10.字符串比较函数strcmp
      int strcmp(const char *s1, const char *s2);
      若s1==s2返回0;s1>s2返回大于0;s1<s2返回小于0
      char *a = "aBcDeF";
      char *b = "AbCdEf";
      char *c = "aacdef";
      char *d = "aBcDeF";
      printf("%d
    ",strcmp(a,b));
      printf("%d",strcmp(a,d));
         
      11.计算字符串长度函数strlen
      计算指定的字符串长度,不包括结束字符'' a
      size_t strlen(const char *s);
      返回字符串s的字符数
      但是sizeof返回的是变量声明后所占的内存数,不是实际长度
      char str[5] = "abcd";
      cout << strlen(str) << endl;//4
      cout << sizeof(str) << endl;//5
     
    
    
     
    基本冒泡排序:
        for(int i=0; i<n-1; i++){
            for(int j=0; j<n-1-i; j++){
                if(a[j]>a[j+1]){
                    int temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
        }
    基本二分查找:
        int left = 0;
        int right = len - 1;
        int mid;
        while( left<=right){
            mid = left + (right - left)/2;//防止溢出
            if(find_data == a[mid]){
                return mid;
            }else if(find_data > a[mid]){
                left = mid + 1;
            }else{
                right = mid - 1;
            }
        }
        return -1;//没有找到
    基本选择排序:
        从待排序的数据中选出最小的元素放在起始位置,然后再从剩余的未排序元素中寻找到最小的元素,放到已排序的序列的末尾
        1.我们的目标是找到最小的数min,放到第一位
        2.我们的目标是,找出除了min以外的最小值,让它排在第2位
        3.重复2直到结束
        for(int i=0; i<a.length-1; i++){//需要几轮,例如a=[1,2,3,4,5]需要4轮,最后一个肯定是最大值
            //每轮遍历开始前,默认第一个数为最小值
            int min = a[i];
            int minIndex = i;
            for(int j=i+1; j<a.length; j++){
                if(min>a[j]){
                    min = a[j];
                    minIndex = j;//记录下标
                }
            }
            //如果最小值改变了,那么交换
            if(min!=a[i]){
                a[minIndex] = a[i];
                a[i] = min;
            }
        }
    基本插入排序:
    	void insertSort(int a[], int n){
    	for(int i=1; i<n; i++){//默认第一个元素a[0],只有一个数,有序 
    		int temp = a[i];//存储当前要插入元素
    		int j = i - 1;
    		while( j>=0 && temp<a[j] ){//从后往前找合适位置 
    			a[j+1] = a[j];//没找到,元素后移 
    			j--;
    		}
    		//此时找到了合适位置
    		//每次没找到都j--所以最后插在j+1位置 
    		a[j+1] = temp; 
    	}
    	//打印 
    	for(int i=0; i<n; i++){
    		cout << a[i] << " ";
    	} 
    }
    
  • 相关阅读:
    为什么处理有序数组比无序数组快?
    LeetCode:Longest Common Prefix
    LeetCode:Container With Most Water,Trapping Rain Water
    LeetCode:Substring with Concatenation of All Words (summarize)
    LeetCode:Pow(x, n)
    LeetCode:Combination Sum I II
    LeetCode:N-Queens I II(n皇后问题)
    LeetCode:Valid Sudoku,Sudoku Solver(数独游戏)
    LeetCode:Divide Two Integers
    LeetCode:Reverse Nodes in k-Group
  • 原文地址:https://www.cnblogs.com/Whgy/p/12301431.html
Copyright © 2020-2023  润新知