【算法导论随笔】第二部分 排序和顺序统计量

8u## 第二部分 排序和顺序统计量

排序

堆排序 即时维护思想

快速排序 二分思想
快速排序的种类
可以试试讨论多轴快排轴数量最优解
https://www.cnblogs.com/littlepage/p/11662266.html
https://blog.csdn.net/u012279452/article/details/84790056

尾递归优化
https://zhuanlan.zhihu.com/p/47876964

计数排序,基数排序
桶排序
(列排序)

中位数和顺序统计量

同时找最小值和最大值:
任意两个元素,比较,较小的和当前的minn比,较大的和当前的maxn比
2个元素3次比较,共需要3n/2次比较而不是2(n-1)次

练习9.1-1
1.每个元素同minn比,大于再同minn2比,小于则更新minn,minn2代替minn 最坏情况比较2(n-1)次
2.https://www.cnblogs.com/phishine/articles/1205351.html 树形结构两两比,n-1次,次小的同树根(最小的)有连边,最多【logn】个,logn-1次比较

选择算法:
1.优化二分,对于大的那边扔掉O(n)
https://www.luogu.com.cn/record/37936181
#include
#include
#include
#include
using namespace std;
int n;
int a[5000005];
int read()
{
int x=0;
char ch=getchar();
while(ch>‘9’||ch<‘0’)
{
ch=getchar();
}
while(ch>=‘0’&&ch<=‘9’)
{
x=x*10+ch-‘0’;
ch=getchar();
}
return x;
}
void swap2(int l,int r)
{
if(l!=r)
a[l] ^= a[r] ^= a[l] ^= a[r];
}
int par(int l,int r)
{
int x=a[r];
int i=l-1;
for(int j=l;j<r;j++)
{
if(a[j]<=x)
{
i++;
swap2(i,j);
}
}
swap2(i+1,r);
return i+1;
}
int ranpar(int l,int r)
{
srand(time(0));
int i=(rand()%(r-l+1))+l;
swap2(r, i);
return par(l, r);
}
int ransel(int l,int r,int c)
{
if(lr)
return a[l];
int t = ranpar(l, r);
int k = t - l+1;
if(c
k)
return a[t];
else if(c<k)
return ransel(l, t - 1,c);
else
return ransel(t + 1, r, c - k);
}
int main()
{
// freopen(“in.txt”,“r”,stdin);
n = read();
int c = read();
c++;
for (int i = 1; i <= n;i++)
{
a[i] = read();
}
printf("%d", ransel(1, n, c));
return 0;
}
2.BFPRT算法,最坏情况依旧是O(n)

#include
#include
using namespace std;
int n;
int a[5000005];
int b[1000005];
int read()
{
int x=0;
char ch=getchar();
while(ch>‘9’||ch<‘0’)
{
ch=getchar();
}
while(ch>=‘0’&&ch<=‘9’)
{
x=x*10+ch-‘0’;
ch=getchar();
}
return x;
}
void insertsort(int a[],int l,int r)
{
for(int i=l+1;i<=r;i++)
{
for(int j=i-1;j>0&&a[j+1]<a[j];j–)
{
swap(a[j],a[j+1]);
}
}
}
int par(int l,int r)
{
int x=a[r];
int i=l-1;
for(int j=l;j<r;j++)
{
if(a[j]<=x)
{
i++;
swap(a[i],a[j]);
}
}
swap(a[i+1],a[r]);
return i+1;
}
int findpos(int l,int r,int x)
{
for(int i=l;i<=r;i++)
{
if(a[i]x) return i;
}
}
int bfprt(int l,int r,int c)
{
int j=1;
for(int i=l;i<=r;j++)
{
insertsort(a,i,i+5<=r?i+5:r);
b[j]=a[i+5<=r?i+2:(r-i)/2+i];
i+=5;
}
insertsort(b,1,j);
int bas=b[(j+1)/2];
int pos=findpos(l,r,bas);
swap(a[pos],a[r]);
int t=par(l,r);
int k = t - l+1;
if(c
k)
return a[t];
else if(c<k)
return bfprt(l, t - 1,c);
else
return bfprt(t + 1, r, c - k);
}
int main()
{
// freopen(“in.txt”,“r”,stdin);
n = read();
int c = read();
for (int i = 1; i <= n;i++)
{
a[i] = read();
}
printf("%d",bfprt(1,n,c));
return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值