算法基础学习
#快速排序
快速排序(quicksort)是20世纪60年代提出的一种算法,类似于归并,也有分治的一种思想,即找到一个基准数,将比它大的放在它的右边,比它小的放在它的左边。
快速排序 | |
---|---|
时间复杂度(最快) | O(nlogn) |
时间复杂度(最慢) | O(N^) |
时间复杂度(平均) | O(nlogn) |
空间复杂度 | O(nlogn) |
稳定性 | 不稳定 |
##我的理解
快速排序是一个典型的双指针算法
我们需要两个指针,一个头指针,一个尾指针,分别从该数组的头元素,尾元素开始移动,维护数组,使之变成有序的排列。
那我们该怎么利用这两个指针维护呢?
如文章开头所说的,我们需要找一个基准数,这个基准数并没有什么要求,但我习惯找中间数mid,在两个前后指针互相靠近的过程中,保证前指针所指的数都小于mid,而后指针所指的数都大于mid。当前指针所指的数不能保证小于mid,前指针停止。同理,当后指针所指向的数不能保证大于mid时,后指针也停止。两个指针都停止后,交换这两个数字,两指针继续工作。直到两个指针相遇,结束这个区间的维护,进入下一个区间的维护。
###代码模板
void quick_sort(int q[],int l,int r)
{
int i = l-1, j = r + 1,x = q[l + r >> 1];
if(l >= r) return;
while(i < j)
{
do i ++ ; while(q[i] < x);
do j -- ; while(q[j] > x);
if(i < j) swap(q[i],q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j+1, r);
}
####例题
题目描述
现有n个正整数,n≤10000,要求出这n个正整数中的第k个最小整数(相同大小的整数只计算一次),k≤1000,正整数均小于30000。
输入格式
第一行为n和k; 第二行开始为n个正整数的值,整数间用空格隔开。
输出格式
第k个最小整数的值;若无解,则输出“NO RESULT”。
输入输出样例
输入
10 3
1 3 3 7 2 5 1 2 4 6
输出
3
说明/提示
n≤10000
#include<bits/stdc++.h>
using namespace std;
const int N = 100100;
int n,k,t;
int a[N],b[N];
bool f[300100];
//快排模板
void sort_quick(int a[],int l,int r)
{
while(l >= r)
return ;
int i = l-1,j = r+1;
int mid = a[l + r >> 1];
while(i < j)
{
do i++;while(a[i] < mid);
do j--;while(a[j] > mid);
if(i < j)
swap(a[i],a[j]);
}
sort_quick(a,l,j);
sort_quick(a,j+1,r);
}
int main()
{
cin >> n >> k;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
if(!f[a[i]])//查重
{
b[t++] = a[i];
f[a[i]] = true;
}
}
sort_quick(b,0,t-1);
if(k > t)
printf("NO RESULT");
//for(int j = 0; j < t; j++)
//printf("%d ",b[j]);
else
printf("%d",b[k-1]);
return 0;
}
本人一见之得,希望大佬指正,谢谢各位!