首页 > 编程语言 >6大常用基础算法

6大常用基础算法

时间:2023-07-20 11:35:02浏览次数:34  
标签:常用 right int 基础 arr 算法 查找 length left

6大常用基础算法

1 冒泡排序(BubbleSort)

基本思想

两个数比较大小,比较大的数下沉,比较小的数冒起来。

时间复杂度 O(n)2

代码

```
int a[]={1 5,4,3,2,8,0,7};
int length=sizeof(a)/size(a[0]);
void asd(int a[],int length){
    int temp;
    for(int i=0;i<length-1;i++){
        for(int j=length-1;j>i;j--){
            if(a[i]>a[j]){
                temp=a[j];
                a[j]=a[i];
                a[i]=temp;
            }
        }
    }
}
```

优化

针对问题

​ 暑假的顺序排好之后,冒泡算法仍然会继续进行下一轮比较。

方案

​ 设置标志位flag ,如果发生了交换flag设置为true:如果没有,设置为false。

​ 这样当一轮比较结束后,如果flag仍然为false,及这一轮没有发生交换,说明数据顺序已经排好,没必要继续进行下去。

代码

int a[]={1 5,4,3,2,8,0,7};
int length=sizeof(a)/size(a[0]);
void asd(int a[],int length){
    int temp;
    boolean flag;
    for(int i=0;i<length-1;i++){
        flag=false;
        for(int j=length-1;j>i;j--){
            if(a[i]>a[j]){
                temp=a[j];
                a[j]=a[i];
                a[i]=temp;
                flag=true;
            }
        }
        if(flag==false)
            break;
    }
}

​ 二分查找即折半查找,是一种相对效率较高的查找方式,但是该算法要求线性表必须采用顺序存储结构,而 且表中元素按关键字有序排列。

算法要求

​ 1 必须采用顺序存储结构。

​ 2 必须按关键字大小有序排列。

时间复杂度 O(log2n)

基本思想

​ 首先,将表中元素按照升序或降序排列。

​ 将表中间位置记录的关键字与查找的关键字相比较,如果二者相等,则查找成功;

​ 否则 利用中间位置记录,将表分成前后两个子表,根据中间关键字与查找的关键字的大小,判断查找前后表。

​ 重复以上过程,直到找到满足条件的关键字,使其查找成功,或者子表不存在为止,此时查找不成功。

二分代码模板1

int binarySearch(vector<int>& nums, int target){
  if(nums.size() == 0)
    return -1;

  int left = 0, right = nums.size() - 1;
  while(left <= right){
    // Prevent (left + right) overflow
    int mid = left + (right - left) / 2;
    if(nums[mid] == target){ return mid; }
    else if(nums[mid] < target) { left = mid + 1; }
    else { right = mid - 1; }
  }

  // End Condition: left > right
  return -1;
}

模板1是二分查找最基础和最基本的形式,是二分的标准模板,该模板可以通过访问数据中的单个索引来确定的元素或条件。

关键属性

二分查找的最基础和最基本的形式。
查找条件可以在不与元素的两侧进行比较的情况下确定(或使用它周围的特定元素)。
不需要后处理,因为每一步中,你都在检查是否找到了元素。如果到达末尾,则知道未找到该元素。

区分语法

初始条件:left = 0, right = length-1
终止:left > right
向左查找:right = mid-1
向右查找:left = mid+1

二分查找模板二

int binarySearch(vector<int>& nums, int target){
  if(nums.size() == 0)
    return -1;

  int left = 0, right = nums.size();
  while(left < right){
    // Prevent (left + right) overflow
    int mid = left + (right - left) / 2;
    if(nums[mid] == target){ return mid; }
    else if(nums[mid] < target) { left = mid + 1; }
    else { right = mid; }
  }

  // Post-processing:
  // End Condition: left == right
  if(left != nums.size() && nums[left] == target) return left;
  return -1;
}

模板二是高级模板,它用于查找需要访问数组中当前索引及其直接右邻居索引的元素·11或条件

关键属性

一种实现二分查找的高级方法。
查找条件需要访问元素的直接右邻居。
使用元素的右邻居来确定是否满足条件,并决定是向左还是向右。
保证查找空间在每一步中至少有 2 个元素。
需要进行后处理。 当你剩下 1 个元素时,循环 / 递归结束。 需要评估剩余元素是否符合条件。

区分语法

初始条件:left = 0, right = length
终止:left == right
向左查找:right = mid
向右查找:left = mid+1

二分查找模板三

int binarySearch(vector<int>& nums, int target){
    if (nums.size() == 0)
        return -1;

    int left = 0, right = nums.size() - 1;
    while (left + 1 < right){
        // Prevent (left + right) overflow
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            return mid;
        } else if (nums[mid] < target) {
            left = mid;
        } else {
            right = mid;
        }
    }

    // Post-processing:
    // End Condition: left + 1 == right
    if(nums[left] == target) return left;
    if(nums[right] == target) return right;
    return -1;
}

模板三用于搜索需要访问当前索引及其在数字中的直接左右邻居索引的元素或条件。

关键属性

实现二分查找的另一种方法。
搜索条件需要访问元素的直接左右邻居。
使用元素的邻居来确定它是向右还是向左。
保证查找空间在每个步骤中至少有 3 个元素。
需要进行后处理。 当剩下 2 个元素时,循环 / 递归结束。 需要评估其余元素是否符合条件。

区分语法

初始条件:left = 0, right = length-1
终止:left + 1 == right
向左查找:right = mid
向右查找:left = mid

3 快速排序(Quicksort)

基本思想

​ 1 从数列中取一个数作为key值

​ 2 将比这个数小的数全部放在他左边,大于等于他的数放在右边

​ 3对左右两个小数列重复第二步操作,直至各区间只有一个数

代码

//快速排序(从小到大)
void quickSort(int left, int right, vector<int>& arr)
{
	if(left >= right)
		return;
	int i, j, base, temp;
	i = left, j = right;
	base = arr[left];  //取最左边的数为基准数
	while (i < j)
	{
		while (arr[j] >= base && i < j)
			j--;
		while (arr[i] <= base && i < j)
			i++;
		if(i < j)
		{
			temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;
		}
	}
	//基准数归位
	arr[left] = arr[i];
	arr[i] = base;
	quickSort(left, i - 1, arr);//递归左边
	quickSort(i + 1, right, arr);//递归右边
}


//快速排序(从大到小)
void quickSort(int left, int right, vector<int>& arr)
{
	if(left >= right) //递归边界条件
		return;
	if(left < 0 || right >= arr.size())
	{
		cout << "error args! array bound." << endl;
		return;
	}//非法输入判断,防止数组越界
	int i, j, base, temp;
	i = left, j = right;
	base = arr[left];  //取最左边的数为基准数
	while (i < j)
	{
		while (arr[j] <= base && i < j)
			j--;
		while (arr[i] >= base && i < j)
			i++;
		if(i < j)
		{
			temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;
		}
	}
	//基准数归位
	arr[left] = arr[i];
	arr[i] = base;
	quickSort(left, i - 1, arr);//递归左边
	quickSort(i + 1, right, arr);//递归右边
}

4 希尔排序(Shell Sort)

基本思想

在要排序的一组数中,根据某一增量分为若干子序列,并对子序列分别进行插入排序。
然后逐渐将增量减小,并重复上述过程。直至增量为1,此时数据序列基本有序,最后进行插入排序。

时间复杂度 O(n1.5)

代码

int arr[] = {34, 27, 55, 8, 97};
int length = sizeof(arr)/sizeof(arr[0]);

// Shell排序算法
void shellSort(int arr[], int length)
{
    int temp = 0;
    int incre = length;
    
    while(true){
        incre = incre/2;
        
        // 根据增量分为若干子序列
        for(int k = 0;k<incre;k++){    
            
            // 对每个子序列进行插入排序
            for(int i=k+incre;i<length;i+=incre){
                
                // 在子序列中进行插入排序
                for(int j=i;j>k;j-=incre){
                    
                    // 如果当前元素比前一个元素小,交换位置
                    if(arr[j]<arr[j-incre]){
                        temp = arr[j-incre];
                        arr[j-incre] = arr[j];
                        arr[j] = temp;
                    }else{
                        break;
                    }
                }
            }
        }
        
        // 当增量减为1时结束排序
        if(incre == 1){
            break;
        }
    }
}

5 选择排序(SelctionSort)

基本思想

在长度为n的无序数组中,第一次遍历n-1个数,找到最小的数与第一个元素交换,

第二次便利n-2个数,找到最小值与第二个元素交换;

循环上述操作,直到第n-1此遍历,找到最小的数值与n-1个元素交换,排序完成。

代码

int arr[] = {34, 27, 55, 8, 97};
int length = sizeof(arr)/sizeof(*arr);
selectSort(arr, length);
//
/// 以小到大排序
void selectSort(int arr[], int length)
{
    for (int i = 0; i < length - 1; i ++) {
        int minIndex = i;
        for (int j = i + 1; j < length; j ++) {
            if (arr[minIndex] > arr[j]) {
                minIndex = j;
            }
        }
        
        /// 找到最小值,进行替换
        if (minIndex != i) {
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }
}

6 插入排序(Insertion Sort)

基本思想

在要排序的一组数中,假定前n-1个数已经排好序,现在将第n个数插到前面的有序数列中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

时间复杂度O(n2)

代码

int arr[] = {34, 27, 55, 8, 97};
int length = sizeof(arr)/sizeof(*arr);
insertSort(arr, length);


/// 以小到大
void insertSort(int arr[], int length)
{
    for (int i = 0; i < length - 1; i ++) {
        for (int j = i + 1; j > 0; j --) {
            if (arr[j] < arr[j - 1]) {
                int temp = arr[j - 1];
                arr[j - 1] = arr[j];
                arr[j] = temp;
            } else { // 当第j-1个数据小于第j个数据时,后面的也就都小于,没必要再遍历
                break;
            }
        }
    }
}

标签:常用,right,int,基础,arr,算法,查找,length,left
From: https://www.cnblogs.com/157184lcy/p/17567832.html

相关文章

  • Ajax基础
    1.全局刷新和局部刷新B/S结构项目中,浏览器(Browse)负责把用户的请求和参数通过网络发送给服务器(Server),服务端使用Servlet(多种服务端技术的一种)接收请求,并将处理结果返回给浏览器。浏览器在html,jsp上呈现数据,混合使用css,js帮助美化页面,或响应事件。1.1全局刷新全......
  • linux(麒麟)常用命令
    1、查看设备名称ls-l/dev/tty*  2、修改文件权限a、直接将此文件改为所有用户可读写chmod777/opt/1.txtr:读数字4w:写数字2x:写数字1可用数字快速表示,如,就是可读,可写,可执行就是4+2+1=7‘777’就表示拥有者,归属组,其他人都可读,可写,可执行。000反之。 b、修......
  • Docker CLI docker container prune 常用命令
    Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化。Docker是内核虚拟化,不使用Hypervisor是不完全虚拟化,依赖内核的特性实现资源隔离。本文主要介绍DockerCLI中......
  • 装饰器/递归/算法
    多层装饰"""语法糖会将紧挨着的被装饰对象的名字当做参数自动传入装饰器函数中"""#判断七句print执行顺序defoutter1(func1):print('加载了outter1')打印顺序③和前面的定义对应defwrapper1(*args,**kwargs):print('执行了wrapper1')打印顺序④......
  • C#城市线路图的纯算法以及附带求极权值
    ​ 常用的数据结构写出来纯属于算法性方面还有待提高时间复杂度最坏情况下O(2^n) 最优:O(n^2)线路图为双向带有权值 比如A-B距离是5000km那么B-A有可能不是5000km所以我在LoadData方法时候没做交换变量直接存放在集合里面以起点递归查找下一连接点并返回当作起点节......
  • postgres 常用命令
    查看查看所有数据库大小SELECTdatnameASdatabase_name,pg_size_pretty(pg_database_size(datname))ASdatabase_sizeFROMpg_database;查看数据库中所有表的大小SELECTtable_name,pg_size_pretty(pg_total_relation_size(quote_ident(table_schema)||'.'||quot......
  • ISP之红外图像增强处理算法
    1、红外图像1.1红外图像特点红外图像一般具有以下特点(一般中长波特点更明显):1)红外图像表征景物的温度分布,反映目标及背景向外辐射能量的差异,是灰度图像,像素分辨率低;2)红外探测气球收到加工工艺影响,靶面分辨率较低,1280x1024分辨率属于高分辨率,640x512的规格较多;3)红外波段会受到......
  • 优化基础4——分支定界法与粒子群算法
    1.分支定界算法王源大佬在这里讲的很清楚,看这个整数规划里面的内容就可以看懂【整数规划(三)】分支定界法及其代码实现-知乎(zhihu.com)主要在于如何分支、如何根据每个节点的上下界确定全局上下界、如何剪枝2.粒子群混合粒子群算法(PSO):C++实现TSP问题-知乎(zhihu.com......
  • 算法练习-day21
    回溯算法77.组合题意:给定两个整数 n 和 k,返回范围 [1,n] 中所有可能的 k 个数的组合。你可以按 任何顺序 返回答案。示例:   思路:本题的思想,主要是利用回溯的思想,先固定tmp插入的个数为k,当检测到tmp的大小等于k时,直接加入到我们的存储组合数组arr中,这时回溯一趟的......
  • MySql基础学习
     一、基础学习1、打开MySql?2、如何创建数据库、数据表? 3、bug 0、注意事项mysql是不区分大小写的 1、启动MySqlcmd命令行,管理员模式运行,输入命令启动服务-----netstartmysql输入ml(命令)----------mqsql-uroot-p出现如下界面就登录成功了 2、基础sql命......