C/C++算法

C/C++算法

本文为网上整理实测。

一、查找算法

1.二分查找

(1)概述
核心思想:将元素分成两部分,如果目标大于中间元素,则重新在右边查找,反之亦然。
要求:有序数组
时间复杂度:O(log2n)
(2)代码实例

#include <iostream>
#include <vector>
using namespace std;

void show(vector<int> &v)
{
    for(int i = 0; i < v.size(); i++) cout<< i << '\t'; cout<<endl;
    for(auto x: v) cout<< x << '\t'; cout<<endl;
}

int binarySearch(vector<int> v,int target)
{
    int left = 0;
    int right = v.size() - 1;

    while(left <= right)
    {
        int mid = (left + right) / 2;
        if(target == v[mid])
            return mid;
        else if(target > v[mid])
        {
            left = mid + 1;
        }
        else
        {
            right = mid - 1;
        }
    }
    return -1;
}

int main()
{
    vector<int> v = {1,2,4,5,7,9,12,13,23,45,46,51,58};
    show(v);
    int x = 0;
    while(cin>>x)
    {
        int site = binarySearch(v,x);
        cout<<"site: "<< site << endl;
    }
    return 0;
}

2.插值查找

(1)概述
基本思想:基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。
也就是将上述的比例参数1/2改进为自适应的,根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字key,这样也就间接地减少了比较次数。
二分查找中查找点计算如下:
mid=(low+high)/2, 即mid=low+1/2*(high-low);
将查找的点改进为:
int mid = left + (right - left) * (target - v[left]) / (v[right] - v[left]);

二、排序算法

数据交换

void swap(int &a, int &b)
{
    int temp = a;
    a = b;
    b = temp;
}

1.冒泡排序(Bubble sort)

(1)概述
核心思想:遍历N次,每次遍历一次将 最大的数放 “末尾”,排好的不参与遍历。
时间复杂度O(n²)
效率分析:最坏(逆序)和 最好都是 O(n²),因为比较的次数没有减少。是稳定的。
空间复杂度O(1)
(2)代码实例

#include <iostream>
#include <vector>
using namespace std;
void swap(int &a,int &b){ int s = a;a = b; b = s;}

vector<int> bubble_sort(vector<int> v)
{
    int n = v.size();
    
    for(int i = 0;i < n;i++)
    {
        for(int j = 1;j < n-i; j++)
        {
            if(v[j-1] > v[j])
                swap(v[j-1],v[j]);
        }
    }
    return v;
}

void show(vector<int> v)
{ for(int i = 0; i < v.size(); i++) { cout<<v[i]<<" ";}cout<<endl;}

int main()
{
    vector<int>v;
    v.push_back(6);v.push_back(9);v.push_back(4);v.push_back(8);
    v = bubble_sort(v); show(v);return 0;
}

2.选择排序

(1)概述
核心思想:从未排序的序列中选出一个最小的,放到左边已排序的末尾。
时间复杂度O(n2),最稳定的排序算法之一
空间复杂度O(1)

(2)代码实例

#include <iostream>
#include <vector>
using namespace std;

inline void swap(int &a,int &b) { int tmp = a; a = b; b = tmp; }
void show(vector<int> v) { for(auto x: v) cout<< x << " "; cout<<endl; }

vector<int>& select_sort(vector<int> &v)
{
    int n = v.size();
    for(int i = 0; i < n - 1; i++) // insert sorted array tail
    {
        int minsite = i;
        for(int j = i + 1; j < n; j++) // find min
        {
            if(v[j] < v[minsite])
                minsite = j;
        }
        swap(v[i],v[minsite]);
    }	
    return v;
}

int main()
{
    vector<int> v = {6,3,5,7,2,8,4,1,5,9,1};
    show(v);
    v = select_sort(v);
    show(v);
    return 0;
}

3.快速排序

快排1
快排2
(1)概述
核心思想:选择一个基准值,将小于基准值的放左边,大的放右边;以后采用递归的方式对左右两边做相同操作(分治法)
时间复杂度平均O(NlogN),最差和冒泡排序一样O(N2)(降序的时候)
空间复杂度
其实这个空间复杂度不太好计算,因为有的人使用的是非就地排序,那样就不好计算了(因为有的人用到了辅助数组,所以这就要计算到你的元素个数了);我就分析下就地快速排序的空间复杂度吧;
首先就地快速排序使用的空间是O(1)的,也就是个常数级;而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据;
最优的情况下空间复杂度为:O(logn) ;每一次都平分数组的情况
最差的情况下空间复杂度为:O( n ) ;退化为冒泡排序的情况
(2)代码实例

#include <iostream>
#include <vector>
using namespace std;

inline void swap(int &a, int &b) { int tmp = a;a = b;b = tmp; }
void show(vector<int> &v) { for(auto x: v) cout<< x <<" "; cout<<endl; }

void  quicksort(vector<int> &v,int left,int right)
{
	if(left >= right)
		return;
	int base = v[left];
	int i = left;
	int j = right;
	
	while(i < j)    
	{               
	    while(v[j] >= base && i < j)
	        j--;    
	    while(v[i] <= base && i < j)
	        i++;    
		if(i < j)
			swap(v[i],v[j]);
	} 
	swap(v[left],v[i]);                     
	quicksort(v,left,i-1);
	quicksort(v,i+1,right); 
}

int main()
{
	vector<int> v = {6,3,5,9,2,8,10,1,4,13,11};
	show(v);
	quicksort(v,0,v.size()-1);
	show(v);
	return 0;	
}

三、其他算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值