排序算法合集

堆排序

平均时间复杂度:O(nlogn) 稳定性:不稳定
思想:
1.先找到第一个非叶子节点 n/2-1,n为数组长度,然后构成大顶堆
2.将堆顶和数组末尾元素交换;
3.对0<j<n的元素重复前面1,2直到有序

#include<iostream>
#include<vector>
using namespace std;
void bigheap(vector<int>&a,int i,int length)
{
	int temp=a[i];//先保存父节点值
	for(int k=2*i+1;k<length;k=k*2+1)//左子节点k*2+1
	{
	   if(k+1<length&&a[k]<a[k+1]) k++;//若左子节点小于右子节点 k指向右子节点
	   if(a[k]>a[i]){
	   a[i]=a[k];
	   i=k;//当子节点大于父节点时 子节点赋值给父节点 且记录下子节点位置为i
	   }
	   else break;
	}
	a[i]=temp;//将父节点值还给子节点
}
void sort(vector<int>&a)
{
	int n=a.size();
	for(int i=n/2-1;i>=0;i--)//生成大顶堆
		bigheap(a,i,n);
	for(int j=n-1;j>0;j--)//交换首末位值 再排序大顶堆
	{
	swap(a[j],a[0]);
	bigheap(a,0,j);
	}
}
int main()
{
	int a1[]={2,3,1,5,6,7,8,10,4,9};
	vector<int>a(a1,a1+10);
	sort(a);
	for(auto i=a.begin();i!=a.end();i++)
	cout<<*i<<" ";
	return 0;
}

在这里插入图片描述

拓扑排序

时间复杂度O(N) 空间复杂度O(N+E(边数)) 稳定性:不稳定
前提
1.图必须是有向图
2.图里面没有环
思想:
1.构建入度数组
2.构建连接值矩阵
3.将入度值为0的i值放入队列
4.对于队列中的i的链接值矩阵更新他们的入度值,并将入度值为压入队列 循环判断 直到队列为空值
在这里插入图片描述
力扣207 课程表
你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。

在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。

例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。

输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
输出:false
解释:总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。

class Solution {
        vector<int>indegree;
        vector<vector<int>>adj;//链接值矩阵
        queue<int>q;
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
            indegree.resize(numCourses,0);
            adj.resize(numCourses,vector<int>());
            for(int i=0;i<prerequisites.size();i++)
            {
                indegree[prerequisites[i][0]]++;//入度值数组
                
                
                adj[prerequisites[i][1]].push_back(prerequisites[i][0]);//链接值矩阵
    
            }
             for (int i=0; i<numCourses; i++) {
                  if (indegree[i] == 0) q.push(i);
                }
             int count=0;
            while(!q.empty())
            {
                int m=q.front();
                count++;
                q.pop();
                for(int i=0;i<adj[m].size();i++)
                {
                    indegree[adj[m][i]]--;
                    if(indegree[adj[m][i]]==0) q.push(adj[m][i]);
                }

            }
            return count==numCourses;
    }
};

快速排序

时间复杂度:O(nlogn) 空间复杂度:O(1) 稳定性:不稳定

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

void fastsort(vector<int>&a1,int low,int high)
{
	if(low>=high) return;
	swap(a1[low+rand()%(high-low)],a1[high]);//将标兵位置放置最后
	int i=low;
	for(int j=low;j<high;j++)
	{
		if(a1[j]<=a1[high])
		{swap(a1[j],a1[i]);i++;}//找寻前后排好序的标兵位置
	}
	swap(a1[i],a1[high]);//交换标兵位置
    fastsort(a1,low,i-1);
	fastsort(a1,i+1,high);
}
int main()
{
	int a[]={3,4,5,1,2};
	vector<int>a1(a,a+5);
	fastsort(a1,0,a1.size()-1);
	return 0;
}

插入排序

时间复杂度:O(n^2) 空间复杂度:O(1) 稳定性:稳定

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

void insertsort(vector<int>&a1)
{
	
	for(int i=0;i<a1.size();i++)
	{
		int cur=i;
		for(int j=i;j>=0;j--)
		{
			if(a1[j]>a1[cur]) 
			{swap(a1[j],a1[cur]);
			  cur=j;
			}
		}
	}
	return;
	
}
int main()
{
	int a[]={6,7,5,1,2};
	vector<int>a1(a,a+5);
	insertsort(a1);
	return 0;
}


归并排序

时间复杂度:O(nlogn) 空间复杂度:O(n) 稳定性:稳定

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

void mergesort(vector<int>&a,int low,int high)
{
	if(low>=high) return;//最后一个元素 直接返回
	vector<int>copy=a;
	int mid=low+(high-low)/2;
	int k=low;
	int i=low;
	int j=mid+1;
	while(k<=high)
	{
  	 if(i>mid)//左边走完了
		 a[k++]=copy[j++];
	 else if(j>high)//右边走完了
		 a[k++]=copy[i++];
	 else if(copy[i]>copy[j])
		 a[k++]=copy[j++];
	 else a[k++]=copy[i++];

	}
	mergesort(a,low,mid);
	mergesort(a,mid+1,high);
	return;
	
}
int main()
{
	int a[]={6,7,5,1,2};
	vector<int>a1(a,a+5);
	 mergesort(a1,0,a1.size()-1);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值