一、快速排序(例题 785、786)
快速排序的基本思路:
大致思路:利用指针将整个数轴划分为左侧>=x右侧<=x的数轴,然后利用递归将左侧>=x的数据采用与前面划分的同样方法,进一步划分,右侧相同,一步步分。
利用指针将整个数轴划分为左侧>=x右侧<=x的数轴的方法:i=l-1,j=r+1,i指针右移若所指数据>=x,则继续右移,直至不满足此条件为止,j指针左移,若j所指数据<=x则继续左移,直至不满足此条件为止,当ij都停止时,ij所指数据进行交换。然后继续左移右移,重复上述操作。
1确定分界点(在这里选取x=(l+r)/2为分界点)
2调整区间(将数轴上>=x的数据分到左侧,>=x分到右边)
3递归处理左右两段(运用循环将数轴中的数据进一步细化,从而达到从而达到从左到右依次增大的一系列数据)
模板:
#include<stdio.h>
#include<stdlib.h>
#define N 100010
int n;
int q[N];
void quick_sort(int q[],int l,int r)
{
if(l>=r) return;//保证数轴上有数据,当l>=r时无数据,直接返回
int x=q[(l+r)>>1],i=l-1,j=r+1; //选择分界点x=q[(l+r)>>1],在这里>>表示字位右移,右移之后的数字变为原来的1/2.指针i、j要+1、—1扩大指针所指数据的范围
while(i<j)
{
do i++; while(q[i]<x);
do j--; while(q[j]>x);
if(i<j)
{
int t=q[i];
q[i]=q[j];
q[j]=t;
} //ij指针都停下,代表不满足上述式子,则调换ij所指数据
} //调整区间
quick_sort(q,l,j);
quick_sort(q,j+1,r); //递归处理左右两段
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&q[i]);
} //利用循环,输入数组q[]中的数据
quick_sort(q,0,n-1); //调用函数对数组进行排序
for(int i=0;i<n;i++)
{
printf("%d ",q[i]);
} //输出重新排序后的数组中的数字 , 注意在这里%d后有空格
return 0;
}
例题785
题目:
给定你一个长度为n的整数数列。
请你使用快速排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n 个整数(所有整数均在1~109109范围内),表示整个数列。
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
数据范围
1≤n≤1000001≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5
答案:
#include<stdio.h>
#include<stdlib.h>
#define N 100010
int n;
int q[N];
void quick_sort(int q[],int l,int r)
{
if(l>=r) return;
int x=q[(l+r)>>1],i=l-1,j=r+1;
while(i<j)
{
do i++; while(q[i]<x);
do j--; while(q[j]>x);
if(i<j)
{
int t=q[i];
q[i]=q[j];
q[j]=t;
}
}
quick_sort(q,l,j);
quick_sort(q,j+1,r);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&q[i]);
}
quick_sort(q,0,n-1);
for(int i=0;i<n;i++)
{
printf("%d ",q[i]);
}
return 0;
}
注意事项:1.中间的while循环不包括quick_sort(q,l,j)和 quick_sort(q,j+1,r)
2.最后面printf("%d ",q[i])中%d后面有空格,一分开各个数字之间
例题786
题目:
给定一个长度为n的整数数列,以及一个整数k,请用快速选择算法求出数列的第k小的数是多少。
输入格式
第一行包含两个整数 n 和 k。
第二行包含 n 个整数(所有整数均在1~109109范围内),表示整数数列。
输出格式
输出一个整数,表示数列的第k小数。
数据范围
1≤n≤1000001≤n≤100000,
1≤k≤n1≤k≤n
输入样例:
5 3
2 4 1 5 3
输出样例:
3
答案:
#include<stdlib.h>
#include<stdio.h>
#define N 100010
int n,k;
int q[N];
void quick_sort(int q[], int l, int r)
{
if (l >= r) return;
int i=l-1,j=r+1,x=q[(l+r)>>1];
while(i<j)
{
do i++;while(q[i]<x);
do j--;while(q[j]>x);
if(i<j)
{
int t=q[i];
q[i]=q[j];
q[j]=t;
}
}
quick_sort(q,l,j);
quick_sort(q,j+1,r);
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
{
scanf("%d",&q[i]);
}
quick_sort(q,0,n-1);
printf("%d ", q[k-1]);
return 0;
}