数据结构与算法分析 (七)
第七章 排序
1.插入排序(insertion sort)
直白点说就是一次把每个元素拿出来,和ta后面的元素比较大小然后如果某个位置使得他比前一个大,比后一个小则插在该位置,依次循环。//以从小到大排序为例
//算法模板
void insertionsort(int a[],int n){
int temp;
for(int i=1;i<n;i++)
for(int j=i;j>0;j--){
if(a[j]<a[j-1]){
temp=a[j];
a[j]=a[j-1];
a[j-1]=temp;
}
}
}
2.桶排序
- 若干个桶,也就是说数据放入许许多多的桶中;
- 每个桶都是有容量的,桶是有一定容积的容器,所以每个桶中可以放多个元素。
- 从整体来看,整个排序更希望桶能够更匀称。(时间更短)
“桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶里。每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序),最后依次把各个桶中的记录列出来记得到有序序列。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是比较排序,他不受到O(n log n)下限的影响。”(引用自百度百科)
例题:小吉是银行的会计师,在处理银行帐目的时候,遇到了一些问题。有一系列整数,其中含有重复的整数,需要去掉重复后,排序输出,你能帮助小吉解决问题吗?
Input
输入数据共2行,第一行输入测试数据个数n,第二行输入这n个整数,整数之间可能有重复,整数之间可能有若干个空格。
n <= 105,所有的整数不超过104。
Output
输出为1行,是这n个数去重后从小到大的排序。
Sample Input
3
4 4 2
Sample Output
2 4
分析:这个题既要排序又要去重,使用桶排序就十分方便了,把相同的数据放在一个桶里,然后每个桶排好序就排好了。
//桶就是a[]数组,以b为数组下标,记录输入数字的个数,输出时,i从头开始遍历,实现了排序。
#include <iostream>
#include <string.h>
using namespace std;
#define N 100000+10
int main(){
int n,a[N],b;
cin>>n;
memset(a,0,sizeof(a));
for(int i=0;i<n;i++){
cin>>b;
a[b]++;
}
for(int i=0;i<N;i++){
if(a[i])
cout<<i<<" ";
}
}
3.快排(quicksort)
1.思想:分治(二分法),递归
2.方法:
-
如果S中的元素个数是0或者1,则返回;
-
取S中的任意一个元素x,为枢纽元;
-
将除去x之外的S所有元素分成两个不相交的集合,以x为分界线;
-
然后递归。
其中枢纽元的选择就决定了算法的速度。
算法模板:(C语言调用)
void quick_sort(int q[],int l,int r){//需要排序的数组q,一堆数组中的第l个数到第r个数
int temp;
if(l>=r) return;
int x=q[(r+l+1)/2],i=l-1,j=r+1;//二分:采用选择中间那个数为枢纽元;
while(i<j)
{
do i++;while(q[i]<x);
do j--;while(q[j]>x);
if(i<j){
temp=q[j];
q[j]=q[i];
q[i]=temp;
}
}
quick_sort(q,l,i-1);//对位置小于x的排序
quick_sort(q,i,r);//对位置大于x的排序;
}
中位数定义:一组数据按从小到大的顺序依次排列,处在中间位置的一个数或最中间两个数据的平均值(如果这组数的个数为奇数,则中位数为位于中间位置的那个数;如果这组数的个数为偶数,则中位数是位于中间位置的两个数的平均值).
给出一组无序整数,求出中位数,如果求最中间两个数的平均数,向下取整即可(不需要使用浮点数)
Input
该程序包含多组测试数据,每一组测试数据的第一行为N,代表该组测试数据包含的数据个数,1 <= N <= 15000.
接着N行为N个数据的输入,N=0时结束输入Output
输出中位数,每一组测试数据输出一行
Sample Input
4
10
30
20
40
3
40
30
50
4
1
2
3
4
0
Sample Output
25
40
2
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
#define N 15000+10
int main(){
int n,a[N];
while(~scanf("%d",&n)&&n){
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
if(n%2==0){
double b=(a[n/2]+a[n/2-1])*1.0/2;
cout<<floor(b)<<endl;
}
else
cout<<a[(n-1)/2]<<endl;
}
}
.。。。。。未完待续