参考:1.数据结构C语言版|第2版;2.力扣;3.2024年数据结构考研复习指导。三个参考分别依次对应文章三个部分。
排序定义:排序是按关键字的非递减或非递增的顺序重新排列记录序列。排序的稳定性:当两个记录的关键字相同并且排序没有改变这两个记录的原有顺序,那我们就说排序是稳定的,反之,排序是不稳定的。内部排序和外部排序:内部排序:完全在内存中完成的排序;外部排序:不完全在内存中完成的排序。
插入排序的基本思想是:每一次排序将一个新的记录插入到已经排序好的子序列当中。
稳定排序
时间复杂度:O ( n 2 ) \left(n^2\right) (n2)
空间复杂度:O ( 1 ) \left(1\right) (1)
#include
using namespace std;
void InsertSort(int *,int);
void print(int *,int);
int main()
{
int n;cin>>n;
int * lb=new int [n];
for (int i=0;i<n;i++)
cin>>lb[i];
InsertSort(lb,n);
print(lb,n);
delete [] lb;
return 0;
}
void InsertSort(int * lb,int len)
{
for (int i=1;i<len;i++)
{
if (lb[i]>=lb[i-1]) continue;
int temp=lb[i],j=i-1;
for (;j>=0 and temp<lb[j];j--)
lb[j+1]=lb[j];
lb[j+1]=temp;
}
}
void print(int * lb,int len)
{
for (int i=0;i<len;i++)
cout<<lb[i]<<" ";
cout<<endl;
}
稳定排序
时间复杂度:O ( n 2 ) \left(n^2\right) (n2)
空间复杂度:O ( 1 ) \left(1\right) (1)
#include
using namespace std;
void BinaryInsertSort(int *,int);
void print(int *,int);
int main()
{
int n;cin>>n;
int * lb=new int [n];
for (int i=0;i<n;i++)
cin>>lb[i];
BinaryInsertSort(lb,n);
print(lb,n);
delete [] lb;
return 0;
}
void BinaryInsertSort(int * lb,int len)
{
for (int i=1;i<len;i++)
{
if (lb[i]>=lb[i-1]) continue;
int l=0,r=i-1,m;
while (l<=r)
{
m=l+(r-l)/2;
if (lb[m]<lb[i]) l=m+1;
else if (m==0 or lb[m-1]<=lb[i]) break;
else r=m-1;
}
int temp=lb[i];
for (int j=i;j>m;j--)
lb[j]=lb[j-1];
lb[m]=temp;
}
}
void print(int * lb,int len)
{
for (int i=0;i<len;i++)
cout<<lb[i]<<" ";
cout<<endl;
}
不稳定排序
时间复杂度:未知
空间复杂度:O(1)
#include
using namespace std;
void ShellInsert(int,int,int *);
void ShellSort(int,int *,int,int *);
void print(int *,int);
int main()
{
int n;cin>>n;
int * lb1=new int [n];
for (int i=0;i<n;i++)
cin>>lb1[i];
int m;cin>>m;
int * lb2=new int [m];
for (int i=0;i<m;i++)
cin>>lb2[i];
ShellSort(n,lb1,m,lb2);
print(lb1,n);
delete [] lb1,lb2;
return 0;
}
void ShellInsert(int delta,int len,int * lb)
{
for (int i=0;i<delta;i++)
for (int j=i+delta;j<len;j+=delta)
{
if (lb[j]>=lb[j-delta]) continue;
int temp=lb[j],k=j-delta;
for (;k>=0 and temp<lb[k];k-=delta)
lb[k+delta]=lb[k];
lb[k+delta]=temp;
}
}
void ShellSort(int n,int * lb1,int m,int * lb2)
{
for (int i=0;i<m;i++)
ShellInsert(lb2[i],n,lb1);
}
void print(int * lb,int len)
{
for (int i=0;i<len;i++)
cout<<lb[i]<<" ";
cout<<endl;
}
交换排序的基本思想是:两两比较两个记录的关键字,一旦发现两个记录不满足要求,则交换两个记录的顺序,直到序列满足要求为止。
稳定排序
时间复杂度:O ( n 2 ) \left(n^2\right) (n2)
空间复杂度:O(1)
#include
using namespace std;
void BubbleSort(int *,int);
void print(int *,int);
int main()
{
int n;cin>>n;
int * lb=new int [n];
for (int i=0;i<n;i++)
cin>>lb[i];
BubbleSort(lb,n);
print(lb,n);
delete [] lb;
return 0;
}
void BubbleSort(int * lb,int len)
{
for (int i=1;i<len;i++)
{
bool flag=true;
for (int j=0;j<len-i;j++)
if (lb[j]>lb[j+1])
{
flag=false;int temp=lb[j];lb[j]=lb[j+1];lb[j+1]=temp;
}
if (flag) break;
}
}
void print(int * lb,int len)
{
for (int i=0;i<len;i++)
cout<<lb[i]<<" ";
cout<<endl;
}
不稳定排序
时间复杂度:O ( n l o g 2 n ) \left(nlog_2n\right) (nlog2n)
空间复杂度:最好O ( l o g 2 n ) \left(log_2n\right) (log2n),最坏O(n)
#include
using namespace std;
int Partition(int *,int,int);
void func(int *,int,int);
void QuickSort(int *,int);
void print(int *,int);
int main()
{
int n;cin>>n;
int * lb=new int [n];
for (int i=0;i<n;i++)
cin>>lb[i];
QuickSort(lb,n);
print(lb,n);
delete [] lb;
return 0;
}
int Partition(int * lb,int left,int right)
{
int pivotkey=lb[left];
while (left<right)
{
while (left<right and lb[right]>=pivotkey) right-=1;
lb[left]=lb[right];
while (left<right and lb[left]<=pivotkey) left+=1;
lb[right]=lb[left];
}
lb[left]=pivotkey;
return left;
}
void func(int * lb,int left,int right)
{
if (left<right)
{
int pivotloc=Partition(lb,left,right);
func(lb,left,pivotloc-1);
func(lb,pivotloc+1,right);
}
}
void QuickSort(int * lb,int len)
{
func(lb,0,len-1);
}
void print(int * lb,int len)
{
for (int i=0;i<len;i++)
cout<<lb[i]<<" ";
cout<<endl;
}
选择排序的基本思想是:每次排序选出关键字最小或最大的记录放在已经排序好的子序列最后或最前。
不稳定排序但是可以稍加修改变为稳定排序。具体来说,只需将“交换”策略更改为“平移”策略即可。
时间复杂度:O ( n 2 ) \left(n^2\right) (n2)
空间复杂度:O ( 1 ) \left(1\right) (1)
#include
using namespace std;
void SelectSort(int *,int);
void print(int *,int);
int main()
{
int n;cin>>n;
int * lb=new int [n];
for (int i=0;i<n;i++)
cin>>lb[i];
SelectSort(lb,n);
print(lb,n);
delete [] lb;
return 0;
}
void SelectSort(int * lb,int len)
{
for (int i=1;i<len;i++)
{
int min_value=lb[i-1],min_value_index=i-1;
for (int j=i;j<len;j++)
if (lb[j]<min_value)
{
min_value=lb[j],min_value_index=j;
}
int temp=lb[i-1];
lb[i-1]=min_value;
lb[min_value_index]=temp;
}
}
void print(int * lb,int len)
{
for (int i=0;i<len;i++)
cout<<lb[i]<<" ";
cout<<endl;
}
不稳定排序
时间复杂度:O ( n l o g 2 n ) \left(nlog_2n\right) (nlog2n)
空间复杂度:O ( 1 ) \left(1\right) (1)
#include
using namespace std;
void HeapAdjust(int *,int,int);
void CreatHeap(int *,int);
void HeapSort(int *,int);
void print(int *,int);
int main()
{
int n;cin>>n;
int * lb=new int [n];
for (int i=0;i<n;i++)
cin>>lb[i];
HeapSort(lb,n);
print(lb,n);
delete [] lb;
return 0;
}
/*数学推导重中之重*/
void HeapAdjust(int * lb,int begin,int end)
{
int temp=lb[begin];
for (int i=2*begin+1;i<=end;i=2*begin+1)
{
if (i+1<=end and lb[i+1]>lb[i]) i+=1;
if (temp>lb[i]) break;
lb[begin]=lb[i];begin=i;
}
lb[begin]=temp;
}
/*数学推导重中之重*/
void CreatHeap(int * lb,int len)
{
for (int i=len/2-1;i>=0;i--)
HeapAdjust(lb,i,len-1);
}
void HeapSort(int * lb,int len)
{
CreatHeap(lb,len);
for (int i=len-1;i>=1;i--)
{
int temp=lb[i];lb[i]=lb[0];lb[0]=temp;
HeapAdjust(lb,0,i-1);
}
}
void print(int * lb,int len)
{
for (int i=0;i<len;i++)
cout<<lb[i]<<" ";
cout<<endl;
}
归并排序的基本思想是:将两个或两个以上的有序表合并成一个有序表的过程。2-路归并(故名思意)。
稳定排序
时间复杂度:O ( n l o g 2 n ) \left(nlog_2n\right) (nlog2n)
空间复杂度:O ( n ) \left(n\right) (n)
#include
using namespace std;
void Merge(int *,int,int,int);
void func(int *,int,int);
void MergeSort(int *,int);
void print(int *,int);
int main()
{
int n;cin>>n;
int * lb=new int [n];
for (int i=0;i<n;i++)
cin>>lb[i];
MergeSort(lb,n);
print(lb,n);
delete [] lb;
return 0;
}
void Merge(int * lb,int left,int middle,int right)
{
int * lb_temp=new int [right-left+1];
int begin1=left,begin2=middle+1,iter=0;
while (begin1<=middle and begin2<=right)
if (lb[begin1]<=lb[begin2]) {lb_temp[iter]=lb[begin1];begin1+=1;iter+=1;}
else {lb_temp[iter]=lb[begin2];begin2+=1;iter+=1;}
while (begin1<=middle) {lb_temp[iter]=lb[begin1];begin1+=1;iter+=1;}
while (begin2<=right) {lb_temp[iter]=lb[begin2];begin2+=1;iter+=1;}
for (int i=0;i<right-left+1;i++)
lb[left+i]=lb_temp[i];
delete [] lb_temp;
}
void func(int * lb,int left,int right)
{
if (left<right)
{
int middle=left+(right-left)/2;
func(lb,left,middle);
func(lb,middle+1,right);
Merge(lb,left,middle,right);
}
}
void MergeSort(int * lb,int len)
{
func(lb,0,len-1);
}
void print(int * lb,int len)
{
for (int i=0;i<len;i++)
cout<<lb[i]<<" ";
cout<<endl;
}
基数排序
只需留个印象就好
稳定排序
时间复杂度:O ( n ) \left(n\right) (n)
空间复杂度:O ( m ) \left(m\right) (m)
学习习题
已经最优
class Solution {
public:
int missingNumber(vector<int>& nums) {
sort(nums.begin(),nums.end());
for (int i=0;i<nums.size();i++)
if (nums[i]!=i) return i;
return nums.size();
}
};
学习习题
已经最优
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> result;
sort(nums.begin(),nums.end());
for (int i=1;i<nums[0];i++)
result.push_back(i);
for (int i=1;i<nums.size();i++)
if (nums[i]-nums[i-1]>1)
for (int j=nums[i-1]+1;j<nums[i];j++)
result.push_back(j);
for (int i=nums[nums.size()-1]+1;i<=nums.size();i++)
result.push_back(i);
return result;
}
};
学习习题
已经最优
bool func(pair<int,int> p1,pair<int,int> p2)
{
if (p1.first>p2.first) return true;
return false;
}
class Solution {
public:
vector<string> findRelativeRanks(vector<int>& score) {
vector<string> result(score.size());
vector<pair<int,int>> lb;
for (int i=0;i<score.size();i++)
lb.push_back(make_pair(score[i],i));
sort(lb.begin(),lb.end(),func);
for (int i=0;i<lb.size();i++)
if (i==0) result[lb[i].second]="Gold Medal";
else if (i==1) result[lb[i].second]="Silver Medal";
else if (i==2) result[lb[i].second]="Bronze Medal";
else result[lb[i].second]=to_string(i+1);
return result;
}
};
学习习题
已经最优
class Solution {
public:
vector<int> findErrorNums(vector<int>& nums) {
sort(nums.begin(),nums.end());
int a=-1,b=nums[0]==1?-1:1;
for (int i=1;i<nums.size();i++)
{
if (nums[i]==nums[i-1]) a=nums[i];
if (nums[i]-nums[i-1]==2) b=nums[i]-1;
}
if (b==-1) b=nums.size();
vector<int> result={a,b};
return result;
}
};
学习习题
已经最优
class Solution {
public:
string s;
bool isAlienSorted(vector<string>& words, string order) {
s=order;
for (int i=1;i<words.size();i++)
if (!func(words[i-1],words[i]))
return false;
return true;
}
bool func(const string & s1,const string & s2)
{
if (s1.find(s2)==0 and s1.size()>s2.size()) return false;
int size=min(s1.size(),s2.size());
for (int i=0;i<size;i++)
{
int x=s.find(s1[i]),y=s.find(s2[i]);
if (x<y) return true;
if (x>y) return false;
}
return true;
}
};
学习习题
已经最优
class Solution {
public:
int heightChecker(vector<int>& heights) {
int result=0;
vector<int> my_vector=heights;
sort(my_vector.begin(),my_vector.end());
for (int i=0;i<heights.size();i++)
result+=heights[i]==my_vector[i]?0:1;
return result;
}
};
练习习题
已经最优
class Solution {
public:
void sortColors(vector<int>& nums) {
int lb[3] {};
for (int i=0;i<nums.size();i++)
lb[nums[i]]+=1;
int iter=0;
for (int i=0;i<3;i++)
for (int j=0;j<lb[i];j++)
{
nums[iter]=i;iter+=1;
}
}
};
练习习题
已经最优
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
return HeapSort(nums,k);
}
void HeapAdjust(vector<int> & nums,int begin,int end)
{
int temp=nums[begin];
for (int i=begin*2+1;i<=end;i=begin*2+1)
{
if (i+1<=end and nums[i+1]>nums[i]) i+=1;
if (temp>nums[i]) break;
nums[begin]=nums[i];begin=i;
}
nums[begin]=temp;
}
void CreateHeap(vector<int> & nums)
{
for (int i=nums.size()/2-1;i>=0;i--)
HeapAdjust(nums,i,nums.size()-1);
}
int HeapSort(vector<int> & nums,int k)
{
CreateHeap(nums);
for (int i=1;i<=k;i++)
{
int temp=nums[0];nums[0]=nums[nums.size()-i];nums[nums.size()-i]=temp;
HeapAdjust(nums,0,nums.size()-i-1);
}
return nums[nums.size()-k];
}
};
练习习题
已经最优
class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
vector<int> result;
sort(nums.begin(),nums.end());
int level=nums.size()/3,count=1,iter=0;
if (count>level)
{
int temp=nums[iter];
result.push_back(temp);
while (iter+1<nums.size() and nums[iter+1]==nums[iter]) iter+=1;
}
iter+=1;
while (iter<nums.size())
{
if (nums[iter]==nums[iter-1]) count+=1;
else count=1;
if (count>level)
{
int temp=nums[iter];
result.push_back(temp);
while (iter+1<nums.size() and nums[iter+1]==nums[iter]) iter+=1;
}
iter+=1;
}
return result;
}
};
进阶习题
已经最优
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
sort(nums.begin(),nums.end());
if (nums[nums.size()-1]<=0) return 1;
int l=0,r=nums.size()-1,m;
while (l<=r)
{
m=l+(r-l)/2;
if (nums[m]<=0) l=m+1;
else if (m==0 or nums[m-1]<=0) break;
else r=m-1;
}
if (nums[m]!=1) return 1;
int result=0;
for (int i=m+1;i<nums.size();i++)
if (nums[i]-nums[i-1]>=2)
{
result=nums[i-1]+1;break;
}
if (result==0) result=nums[nums.size()-1]+1;
return result;
}
};
有些题目特别傻逼,不要过多进行纠结。