--1 排序与查找 基础算法
2017-07-17 18:31
316 查看
对于排序,常规而言,有几种可以手动实现的排序方式。
一是选择排序,将a[1]......a
的序列进行排序,其实现代码见下:
代码附下:
对数列每个元素的值较小的情况下,也有计数排序(是这么叫哈?)一途,
即输入时统计元素值出现次数,再循环输出即可
当然如果元素值可能为负,可以进行数组平移,即定义a[i+maxn]=a[i].
当然,上述几种算法并不在算法竞赛中经常投入使用,因为它们的时间复杂度O(n2)实在令人难以接受。
------------------------------------------------------------------------------
就便利而言,STL模板中的sort函数显得更加常用。
引用<algorithm> 库后 ,可以使用sort()函数;
对sort的调用就又有几种情况了
一、缺省定义
对a[1]....a
排序; 有如下几种方式 sort(a+1,a+n+1);
在缺省定义下,sort函数有两个参数需要输入;
第一个参数的意义为首元素的地址,
第二个参数的意义为末元素的后一个元素的地址。
缺省定义下sort默认进行从小到大排序;
二、自定义比较函数
如所示代码,
调用方式:
sort(a+1,a+n+1,mycmp);
将进行你自定义的比较行为,
三、如果排序对象是结构体
那么同样需要用到自定义比较函数或者是在结构体内进行符号重定义
e.g.:
如一次考试成绩,有语文,英语,数学三科成绩和学号属性,要求进行多关键字排序
总分高的排前面,
总分相同的数学成绩高的排前面,
数学成绩相同的语文成绩高的排前面,
语文成绩相同的学号小的排前面,
定义结构体:
all自然等于 math+chi+eng
定义自定义比较函数
如上,如果满足条件直接跳出,
否则进行下一次判断
或者对结构体进行符号重定义
嗯,如上
可以观察两种方式非常相似,选择哪一种方式还是看自己习惯吧,我觉得。
---------------------------------------------------------------------------------
STL库中还提供了几种便利的二分查找函数。
upper_bound(),lower_bound(),binary_search();
当然这几个函数用二分为基础优化算法是建立在已排好序的队列(且应为递增序列)当中运行的,
如果是乱序数组,将会得出错误结果。
下面对三种函数进行功能的简述
1、upper_bound() 寻找数列中第一个大于某一值的元素的位置
2、lower_bound() 寻找数列中第一个大于等于某一值的元素的位置
3、binary_search() 在序列查找某一值是否存在,如果存在 则返回 true,否则返回 false
三种函数的调用
bool p=binary_search(A+1,A+n+1,v); //存在性判断
int p=lower_bound(A+1,A+n+1,v)-A; //元素下标 若不存在为 n+1
int p=upper_bound(A+1,A+n+1,v)-A; // 元素下标 若不存在为 n+1
顺便一提,分治算法也可以实现快速排序,复杂度为O(nlog2n)
思想为二分序列,整理左侧序列,整理右侧序列,进行二路归并,实现整个序列有序;
代码附上:
void devide(int *a ,int x,int y)
{
if(y-x==1) return;
int m=(x+y)/2;
devide(a,x,m);
devide(a,m,y);
int i=x,j=m,k=x;
while(i<m&&j<y)
{
if(a[i]>a[j]) t[k++]=a[j++];
else t[k++]=a[i++];
}
while(i<m) t[k++]=a[i++];
while(j<y) t[k++]=a[j++];
for(int p=x;p<y;p++)
{
a[p]=t[p];
}
}
一是选择排序,将a[1]......a
的序列进行排序,其实现代码见下:
void select_sort(int *a) { for(int i=1;i<n;i++) //进行 n-1 轮选择 for(int j=i+1;j<=n;j++) //第 i 轮选择是选择第 i 大元素排在 A[i]。 if(a[i]<a[j]) swap(a[i],a[j]); }第二种较常听说的即为冒泡排序,其思路大致就像泡泡上冒,将最 大/小 的 元素值 向前冒。
代码附下:
void bubble_sort(int *a) { for(int i=1;i<n;i++) //进行 n-1 轮冒泡 for(int j=1;j<=n-i;j++) //第 i 轮冒泡把第 i 大排在 a[n-i+1]的 if(a[j]>a[j+1]) swap(a[j],a[j+1]); }
对数列每个元素的值较小的情况下,也有计数排序(是这么叫哈?)一途,
即输入时统计元素值出现次数,再循环输出即可
void sort() { int a[maxn],maxv=0; // maxv统计元素值最大值; for(int i=1;i<=n;i++) { int x; scanf("%d",&x); a[x]++; // 统计x出现次数; maxv=max(maxv,x); } for(int i=1;i<=maxv;i++) { if(a[i]) printf("%d\n",i); } }
当然如果元素值可能为负,可以进行数组平移,即定义a[i+maxn]=a[i].
当然,上述几种算法并不在算法竞赛中经常投入使用,因为它们的时间复杂度O(n2)实在令人难以接受。
------------------------------------------------------------------------------
就便利而言,STL模板中的sort函数显得更加常用。
引用<algorithm> 库后 ,可以使用sort()函数;
对sort的调用就又有几种情况了
一、缺省定义
对a[1]....a
排序; 有如下几种方式 sort(a+1,a+n+1);
sort(&a[1],&a[n+1]);
在缺省定义下,sort函数有两个参数需要输入;
第一个参数的意义为首元素的地址,
第二个参数的意义为末元素的后一个元素的地址。
缺省定义下sort默认进行从小到大排序;
二、自定义比较函数
bool mycmp(int a,int b) //如果 a 排在 b 的前面,则返回 true { return a>b; //如果 a>b 则 a 排在 b 的前面 }
如所示代码,
调用方式:
sort(a+1,a+n+1,mycmp);
将进行你自定义的比较行为,
三、如果排序对象是结构体
那么同样需要用到自定义比较函数或者是在结构体内进行符号重定义
e.g.:
如一次考试成绩,有语文,英语,数学三科成绩和学号属性,要求进行多关键字排序
总分高的排前面,
总分相同的数学成绩高的排前面,
数学成绩相同的语文成绩高的排前面,
语文成绩相同的学号小的排前面,
定义结构体:
struct stu { int id 4000 ,math,chi,eng,all; };
all自然等于 math+chi+eng
定义自定义比较函数
bool cmp(stu a,stu b) { if(a.all!=b.all) return a.all<b.all; // 总成绩靠前 if(a.math!=b.math) return a>b //数学靠前 if(a.chi!=b.chi) return a.chi>b.chi; if(a.eng!=b.eng) return a.eng<b.eng; return a.id<b.id; }
如上,如果满足条件直接跳出,
否则进行下一次判断
或者对结构体进行符号重定义
嗯,如上
struct stu { int id,math,chi,eng,all; bool friend bool operator < (stu a,stu b) {
if(a.all!=b.all) return a.all<b.all; // 总成绩靠前 if(a.math!=b.math) return a>b //数学靠前 if(a.chi!=b.chi) return a.chi>b.chi; if(a.eng!=b.eng) return a.eng<b.eng; return a.id<b.id;}};
可以观察两种方式非常相似,选择哪一种方式还是看自己习惯吧,我觉得。
---------------------------------------------------------------------------------
STL库中还提供了几种便利的二分查找函数。
upper_bound(),lower_bound(),binary_search();
当然这几个函数用二分为基础优化算法是建立在已排好序的队列(且应为递增序列)当中运行的,
如果是乱序数组,将会得出错误结果。
下面对三种函数进行功能的简述
1、upper_bound() 寻找数列中第一个大于某一值的元素的位置
2、lower_bound() 寻找数列中第一个大于等于某一值的元素的位置
3、binary_search() 在序列查找某一值是否存在,如果存在 则返回 true,否则返回 false
三种函数的调用
bool p=binary_search(A+1,A+n+1,v); //存在性判断
int p=lower_bound(A+1,A+n+1,v)-A; //元素下标 若不存在为 n+1
int p=upper_bound(A+1,A+n+1,v)-A; // 元素下标 若不存在为 n+1
顺便一提,分治算法也可以实现快速排序,复杂度为O(nlog2n)
思想为二分序列,整理左侧序列,整理右侧序列,进行二路归并,实现整个序列有序;
代码附上:
void devide(int *a ,int x,int y)
{
if(y-x==1) return;
int m=(x+y)/2;
devide(a,x,m);
devide(a,m,y);
int i=x,j=m,k=x;
while(i<m&&j<y)
{
if(a[i]>a[j]) t[k++]=a[j++];
else t[k++]=a[i++];
}
while(i<m) t[k++]=a[i++];
while(j<y) t[k++]=a[j++];
for(int p=x;p<y;p++)
{
a[p]=t[p];
}
}
相关文章推荐
- 算法基础:排序与查找
- 算法基础-->排序查找
- JAVA基础day04 数组学习 排序和查找基本算法
- 基础算法-查找:折半查找
- 基础算法-查找:线性索引查找(II)
- 【基础算法】排序-复杂排序之一(归并排序的两种优化讨论)
- C#算法基础之递归排序
- C++ 基础算法之二分查找
- C++——算法基础之排序——快速排序
- 算法基础:排序(二)——归并排序——Python实现
- C基础算法之二分法查找
- 算法基础之----直接交换排序
- 基础算法--排序: 之插入排序
- 基础算法-直接选择排序
- JAVA基础算法——将字符串按照字典倒序排序并输出
- 算法专题----程序员必须知道的8大排序和3大查找
- 第16周 外部查找之验证算法(1)直接插入排序
- 【数据结构与算法基础】单链表及其应用基数排序 / Singly Linked List and radix sort
- 排序算法之二分查找
- 查找""排序""简单数学计算" "简单算法"[Java实现](数据结构和算法)(复习)(持续更新