堆排序
平均时间复杂度: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;
}