常用六大排序算法的实现

非原创,协会里爬的

插入排序(insertion_sort)

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

// 插入排序
void insertion_sort(vector<int>& a)
{
    for(int i=0;i<a.size();i++)// 从第一个开始做插入
    {
        int t=a[i],j;// 存储数据
        for(j=i-1;j>=0;j--)// 从前一个数开始作比较
            if(t<a[j]) a[j+1]=a[j]; // 若前一个数比当前数大,则后一个数放前一个数
            else break;// 否则退出
        a[j+1]=t; // 后一个数放存储的数值,这个插入操作必须放在循环外面
    }
}

int main()
{
    int n;
    vector<int> a;
    
    cin>>n;
    for(int i=0,t;i<n;i++)
    {
        cin>>t;
        a.push_back(t);
    }
    
    insertion_sort(a);
    
    for(int i=0;i<n;i++)cout<<a[i]<<" ";
    return 0;
}

堆排序(heap_sort)

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


int n,m;
vector<int> heap;

// 从小到大排序建大根堆,因为根节点要放到最后面
// 从大到小排序建小根堆

//堆中,默认下标0弃置,下标1的元素为根节点


//大根堆,下沉操作
void push_down(vector<int>& heap,int size,int u)
{
    int t=u,left=u*2,right=u*2+1;
    if(left<=size && heap[left]>heap[t])t=left;//不越界,并且左子树较大
    if(right<=size && heap[right]>heap[t])t=right;//不越界,并且右子树较大
    if(t!=u)//如果存在更大的值
    {
        swap(heap[u],heap[t]);//交换
        push_down(heap,size,t);//下沉
    }
}

//大根堆,上浮操作
void push_up(vector<int>& heap,int u)
{
    while(u/2 && heap[u/2]<heap[u])//如果没有越界,并且父节点更小
    {
        swap(heap[u/2],heap[u]);//交换
        u/=2;//上移
    }
}

//堆排序
void heap_sort(vector<int>& heap,int size)
{
    int n=size;
    for(int i=1;i<=n;i++)push_up(heap,i);//建堆,像插入一样、上浮
    
    //堆排序
    for(int i=1;i<=n;i++)//排序n次
    {
        swap(heap[1],heap[size]);//将根节点(最大的数)放到最后面
        size--;//数量--
        push_down(heap,size,1);
    }
}


int main()
{
    cin>>n>>m;
    heap.resize(n+1);
    
    for(int i=1;i<=n;i++)cin>>heap[i];
    
    heap_sort(heap,n);//排序堆中的前n个数
    
    for(int i=1;i<=m;i++)cout<<heap[i]<<' ';
    return 0;
}

归并排序(merge_sort)

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

void merge_sort(vector<int>& a,int l,int r)
{
    if(l>=r)return;//此处的=号可以解决边界问题
    
    int mid=(l+r)/2; // 去中间值
    merge_sort(a,l,mid);//递归
    merge_sort(a,mid+1,r);
    
    static vector<int> st;
    st.clear();
    int i=l,j=mid+1;
    while(i<=mid && j<=r)//归并
        if(a[i]<a[j])st.push_back(a[i++]);
        else st.push_back(a[j++]);
        
    //处理剩余元素
    while(i<=mid)st.push_back(a[i++]);
    while(j<=r)st.push_back(a[j++]);
    
    // 此处建议像如下一样,采用双指针的写法 
    for(i=0,j=l;i<st.size();i++,j++)a[j]=st[i];//覆盖
}

int main()
{
    int n;
    vector<int> a;
    
    cin>>n;
    for(int i=0,t;i<n;i++)
    {
        cin>>t;
        a.push_back(t);
    }
    
    merge_sort(a,0,a.size()-1);
    
    for(int i=0;i<n;i++)cout<<a[i]<<" ";
    return 0;
}

快速排序(quick_sort)

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

// 快速排序
void quick_sort(vector<int>& a,int l,int r)
{
    if(l>=r)return;
    
    int i=l-1,j=r+1,x=a[(l+r)>>1];//x可以是一个随机数,此处选择中间的数
    while(i<j)
    {
        do i++;while(a[i]<x);//此处是一个双指针
        do j--;while(a[j]>x);
        if(i<j)swap(a[i],a[j]);//交换
        else quick_sort(a,l,j),quick_sort(a,j+1,r);//递归,此处参数必须是 j
    }
}

int main()
{
    int n;
    vector<int> a;
    
    cin>>n;
    for(int i=0,t;i<n;i++)
    {
        cin>>t;
        a.push_back(t);
    }
    
    quick_sort(a,0,a.size()-1);
    
    for(int i=0;i<n;i++)cout<<a[i]<<" ";
    return 0;
}

冒泡排序(bubble_sort)

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

vector<int> a;

// 冒泡排序 
void bubble_sort(vector<int>& a)
{
    bool f=false;//交换标记 
    for(int i=a.size()-1;i>0;i--)//可以比较的最后一个数 
    {
        for(int j=0;j+1<=i;j++)//从0开始,比较到最后一个数 
            if(a[j]>a[j+1])
            {
                swap(a[j],a[j+1]);
                f=true;
            }
        if(f==false)return;//不存在交换,说明已经排好序了,直接返回,这是一个小优化 
    }
}

int main()
{
    int n;
    cin>>n;// 输入 
    for(int i=0,t;i<n;i++)
    {
        cin>>t;
        a.push_back(t);
    }
    
    bubble_sort(a);
    
    // 输出 
    for(int i=0;i<n;i++)cout<<a[i]<<" ";
    return 0;
}

选择排序(selection_sort)

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

//选择排序
void selection_sort(vector<int>& a)
{
    for(int i=0;i<a.size();i++)// 选择第i个数
        for(int j=i+1;j<a.size();j++)// 和第j个数比较
            if(a[j]<a[i])// 若比第i个数小,交换两个数
                swap(a[i],a[j]);
}

int main()
{
    int n;
    vector<int> a;
    
    cin>>n;
    for(int i=0,t;i<n;i++)
    {
        cin>>t;
        a.push_back(t);
    }
    
    selection_sort(a);
    
    for(int i=0;i<n;i++)cout<<a[i]<<" ";
    return 0;
}

高精度

高精度-乘法

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

//一个大数A * 一个正常int型整数B 
int main()
{
	string a;
	int b;
	cin>>a>>b;
	
	vector<int> A;
	for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
	
	vector<int> C;
	for(int i=0,t=0;i<A.size()||t;i++)
	{
		if(i<A.size())t+=A[i]*b;//此处和加法类似 
		C.push_back(t%10);
		t/=10;
	}
	while(C.size()>1 && C.back()==0)C.pop_back();
	
	for(int i=C.size()-1;i>=0;i--)cout<<C[i];
	return 0;	
} 

高精度-除法

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

int main()
{
	string a;
	int b;
	cin>>a>>b;
	
	vector<int> A;
	for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
	
	vector<int> C;
	for(int i=A.size()-1,t=0;i>=0;i--) 
	{
		t*=10;
		t+=A[i];
		C.push_back(t/b);
		t%=b;
	}
	while(C.size()>1 && C.front()==0)C.erase(C.begin());//ČĽłýÇ°ľź0 
	
	for(int i=0;i<C.size();i++)cout<<C[i];
	
	return 0;
} 

高精度-加法

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

int main()
{
	string a,b;
	vector<int> A,B;
	cin>>a>>b;
	for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');//前面是低位,后面是高位 
	for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
	vector<int> C;
	for(int i=0,t=0;i<A.size() || i<B.size() || t;i++)
	{
		if(i<A.size())t+=A[i];
		if(i<B.size())t+=B[i];
		C.push_back(t%10);
		t/=10;
	}
	for(int i=C.size()-1;i>=0;i--)cout<<C[i];
	return 0;
} 

高精度-减法

#include<iostream>
#include<string>
#include<vector>
using namespace std;
const int N=1000010;

typedef vector<int> vec;

bool cmp(vec& A,vec& B)//判断A是否大于B 
{
	if(A.size()!=B.size())return A.size()>B.size();
	for(int i=A.size()-1;i>=0;i--)//后面是高位 
		if(A[i]!=B[i])
			return A[i]>B[i];
	return true;//两数相等 
} 
vec sub(vec& A,vec& B)// C=A-B 满足 A>B , A>0 , B>0  
{
	vec C;
	for(int i=0,t=0;i<A.size();i++)
	{
		t=A[i]-t;//加上A[i],减去借位 
		if(i<B.size())t-=B[i];
		C.push_back((t+10)%10);// 2-5=-3  ->   12-5=7
		if(t<0)t=1;//t<0代表有借位 
		else t=0;
	}
	while(C.size()>1 && C.back()==0)C.pop_back();//去除前导零
	return vec(C.rbegin(),C.rend());//翻转
}
 
int main()
{
	string a,b;
	vector<int> A,B;
	cin>>a>>b;
	for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
	for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
	
	vector<int> C;
	if(cmp(A,B))C=sub(A,B);
	else C=sub(B,A);
	
	for(int i=0;i<C.size();i++)cout<<C[i];
	return 0;
} xxxxxxxxxx #include<iostream>#include<string>#include<vector>using namespace std;const int N=1000010;typedef vector<int> vec;bool cmp(vec& A,vec& B)//判断A是否大于B {    if(A.size()!=B.size())return A.size()>B.size();    for(int i=A.size()-1;i>=0;i--)//后面是高位         if(A[i]!=B[i])            return A[i]>B[i];    return true;//两数相等 } vec sub(vec& A,vec& B)// C=A-B 满足 A>B , A>0 , B>0  {    vec C;    for(int i=0,t=0;i<A.size();i++)    {        t=A[i]-t;//加上A[i],减去借位         if(i<B.size())t-=B[i];        C.push_back((t+10)%10);// 2-5=-3  ->   12-5=7        if(t<0)t=1;//t<0代表有借位         else t=0;    }    while(C.size()>1 && C.back()==0)C.pop_back();//去除前导零    return vec(C.rbegin(),C.rend());//翻转} int main(){    string a,b;    vector<int> A,B;    cin>>a>>b;    for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');    for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');        vector<int> C;    if(cmp(A,B))C=sub(A,B);    else C=sub(B,A);        for(int i=0;i<C.size();i++)cout<<C[i];    return 0;} 

双高精度-乘法

#include<iostream>
#include<string>
#include<vector>
using namespace std;
const int N=1000010;

typedef vector<int> vec;

bool cmp(vec& A,vec& B)//判断A是否大于B 
{
	if(A.size()!=B.size())return A.size()>B.size();
	for(int i=A.size()-1;i>=0;i--)//后面是高位 
		if(A[i]!=B[i])
			return A[i]>B[i];
	return true;//两数相等 
} 
vec sub(vec& A,vec& B)// C=A-B 满足 A>B , A>0 , B>0  
{
	vec C;
	for(int i=0,t=0;i<A.size();i++)
	{
		t=A[i]-t;//加上A[i],减去借位 
		if(i<B.size())t-=B[i];
		C.push_back((t+10)%10);// 2-5=-3  ->   12-5=7
		if(t<0)t=1;//t<0代表有借位 
		else t=0;
	}
	while(C.size()>1 && C.back()==0)C.pop_back();//去除前导零
	return vec(C.rbegin(),C.rend());//翻转
}
 
int main()
{
	string a,b;
	vector<int> A,B;
	cin>>a>>b;
	for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
	for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
	
	vector<int> C;
	if(cmp(A,B))C=sub(A,B);
	else C=sub(B,A);
	
	for(int i=0;i<C.size();i++)cout<<C[i];
	return 0;
} 

两个高精度乘法

双高精度-除法(滚动减法模拟除法)

#include<iostream>
#include<string>
#include<vector>
using namespace std;
typedef vector<int> vec;

int cmp(vec A,vec B)//比较大小 > = < 对应 1 0 -1 
{
	if(A.size()!=B.size())
		if(A.size()>B.size())return 1;
		else return -1;
	for(int i=0;i<A.size();i++)
		if(A[i]!=B[i])
			if(A[i]>B[i])return 1;
			else return -1;
	return 0;
}

vec sub(vec A,vec B)//减法 
{
	A=vec(A.rbegin(),A.rend());
	B=vec(B.rbegin(),B.rend());
	
	vec C;
	for(int i=0,t=0;i<A.size();i++)
	{
		t=A[i]-t;
		if(i<B.size())t-=B[i];
		C.push_back((t+10)%10);
		if(t<0)t=1;
		else t=0;
	}
	while(C.size()>1 && C.back()==0)C.pop_back();
	
	return vec(C.rbegin(),C.rend());
}

pair<vec,vec> div(vec A,vec B)//滚动减法模拟除法 
{
	int initsize=B.size();//记录除数的初始位数 
	while(A.size()>B.size())B.push_back(0);//除数扩大到极限 
	
	vec C;
	while(1)
	{
		int t=0;//减的次数 
		for(t=0;cmp(A,B)>=0;t++)A=sub(A,B);//A>=B就减 
		C.push_back(t); 
		if(B.size()==initsize)break;//到达除数本身,除法结束 
		else B.pop_back();//除数%10 
	}
	while(C.size()>1 && C.front()==0)C.erase(C.begin());//去除前导0 
	
	return pair<vec,vec>(C,A);//返回结果 
}

int main()
{
	string a,b;
	cin>>a>>b;
	
	vector<int> A,B;
	for(int i=0;i<a.size();i++)A.push_back(a[i]-'0');
	for(int i=0;i<b.size();i++)B.push_back(b[i]-'0');
	
	pair<vec,vec> C;
	C=div(A,B);//A除B,返回值为 商和余 
	
	vec t=C.first;//输出 
	for(int i=0;i<t.size();i++)cout<<t[i];
	cout<<endl;
	t=C.second;
	for(int i=0;i<t.size();i++)cout<<t[i];
	
	return 0;
}