- 插入排序
直接插入排序 折半插入排序 二路插入排序 表插入排序 希尔排序
- 交换排序
冒泡排序 快速排序
- 选择排序
简单选择排序 堆排序
- 归并排序
2-路归并排序
- 基数排序
1 插入排序
1.1直接插入排序
从第2个元素起,将第i个元素插入前i-1个有序的元素中。从i-1位置向前遍历寻找插入位置,边寻找插入位置边后移元素。
/**
* 直接插入排序:
* 将第i个元素插入前有序的i-1个序列中
*/
public static void insertSort(int src[]){
int len=src.length,j=0;
int guard=0;
for(int i=1;i<len;i++){//准备插入第i个元素
guard=src[i];
for(j=i-1;j>=0 && src[j]>guard;j--){//如果src[0]位置空出来的话,就将它设置为哨兵,能较少比较的次数
//这里每次不需要每次都交换元素
src[j+1]=src[j];//后移
}
src[j+1]=guard;//到位需要插入的元素
}
}
1.2折半插入排序
在直接插入排序的基础上用二分查找寻找插入位置,减少比较次数,移动元素的次数相同。
/**
* 折半插入排序
* 再直接插入排序的基础上通过折半查找算法
* 减少了定位src[i]插入点的时候比较的次数,
* 但是元素后移的次数不变
* @param src
*/
public static void bInsetSort(int src[]){
int len=src.length,j=0;
int low=0,high=0,mid=0;//折半查找的指针
int guard=0;//保存src[i]
for(int i=1;i<len;i++){
guard=src[i];
low=0;high=i-1;
//1 在src[low…high]中折半查找有序插入的位置
while(low<=high){
mid=(low+high)/2;
if(src[mid]>=guard){//插入点在低半区
high=mid-1;
}else{//插入点在高半区
low=mid+1;
}
}
//while最后一次循环有两种情况(guard一直都在low~high范围内):
//1 low==high,若src[mid]>=guard,保证稳定的插入点在high+2位置,high+1位置亦可插入
//若src[mid]<guard,保证稳定的插入点在high+1位置,high+2不可插入
//2 high=low+1,的情况都会转化为low==high的情况,而high=low+j(j>=2)的情况都回也都回转化
//2 记录后移
for(j=i-1;j>=high+1;j--){//不一定稳定后移
src[j+1]=src[j];
}
src[high+1]=guard;
}
}
1.3二路插入排序
用到一个新的数组。 int src[] = {49,38,65,97,76,13,27,
49}
第一步
第二步
第三步
第四步
第五步
第六步
| | | final | | first | |
49 | 65 | 76 | 97 | * | 13 | 27 | 38 |
第七步
| | | | final | first | |
49 | 49 | 65 | 76 | 97 | 13 | 27 | 38 |
1.4表插入排序
用静态链表的存储结构。
1.5希尔排序
/**
* 希尔排序
* 按增量序列dlta[0…t-1]分别使相隔某个增量的
* 子序列有序,直到最后的增量为1,整个序列都
* 有序
* @param src
*/
public static void shellSort(int src[],int dlta[]){
int t=dlta.length;
//按增量dlta[0…t-1]堆顺序表src做希尔排序
for(int k=0;k<t;k++){
shellInsert(src,dlta[k]);
}
}
private static void shellInsert(int src[],int dk){
int len=src.length;
int third,j;
//对序列src做一趟插入排序,相比于直接插入排序,增量变为dk
for(int i=dk;i<len;i++){//将元素src[i]插入合适的位置
third=src[i];
for(j=i-dk;j>=0 && src[j]>third;j-=dk){
src[j+dk]=src[j]; //记录后移
}
src[j+dk]=third; //插入合适的位置
}
}
2交换排序
2.1冒泡排序
/**
* 冒泡排序
* 从前往后比较的同时交换元素,最终将最大的元素置于最后的位置
*
* 改进的空间是:在一趟排序过程中没有交换记录的操作就结束整个排序过程
*/
public static void bubbleSort(int src[]){
int len=src.length;
int third=0;
boolean flag=false;
for(int i=len-1;i>0;i--){//选出src[i]位置的元素
flag=false;
for(int j=0;j<i;j++){
if(src[j]>src[j+1]){
//交换元素
third=src[j+1];
src[j+1]=src[j];
src[j]=third;
flag=true;
}
}
if(!flag){
break;
}
}
}
2.2快速排序
快速排序使用分治思想,用枢轴元素将整个序列分为两块,分块的时候从两头向中间遍历一次。
快速排序一次交换:
快速排序整个过程:
/**
* 快速排序
* 确定枢轴元素,然后将小的置于中轴元素之前,大的置于中轴元素之后
* 递归这个过程直到结束
* @param src
*/
public static void qSort(int src[],int low,int high){
if(low<high){//只剩下一个元素的时候就结束递归
int pivotLoc=partition(src,low,high);
qSort(src,low,pivotLoc-1);//对低子表进行排序,其中pivotLoc是枢轴位置
qSort(src,pivotLoc+1,high);//对高子表进行排序
}
}
//快速排序中一趟排序的算法
//交换子表中src[low…high]的记录,枢轴元素到位,并返回其位置,此时
//在它之前(后)的元素均不大(小)于它
private static int partition(int src[],int low,int high){
int pivot=src[low];//用子表的第一个记录做枢轴元素
while(low<high){
//从两天遍历向中间靠拢,只遍历一次,不回溯
while(src[high]>=pivot && low<high){high--;}
src[low]=src[high];//把比枢轴元素小的元素移动到低端
while(src[low]<=pivot && low<high){low++;}
src[high]=src[low];
}
//只有当low==high才结束循环,此时src[low]之前的元素都能保证小于枢轴元素,
//之后的元素都能保证大于枢轴元素。并且已经保存了该位置的副本,故low(或high)
//位置就是枢轴元素要插入的位置
src[low]=pivot;
return low;
}
3选择排序
3.1简单选择排序
选出最小的元素与i位置的元素交换,选择的过程中无需交换只需保存最小元素的索引值。
/**
* 简单选择排序
* 通过n-i趟比较选出最小的元素与i位置的元素交换(选择过程中无需移动元素)
*/
public static void selectSort(int src[]){
int min=0,len=src.length;
int third=0;
for(int i=0;i<len;i++){
min=i;
for(int j=i+1;j<len;j++){
if(src[j]<src[min]){min=j;}
}
//将一趟比较后最小的元素移动到src[i]
third=src[min];
src[min]=src[i];
src[i]=third;
}
}
3.2堆排序
堆定义:
小顶堆:k(i)<=k(2i) && k(i)<=k(2i+1)
大顶堆:k(i)>=k(2i) && k(i)>=k(2i+1)
(i=1,2,…,n/2向下取整)
1 先将无序序列调整堆结构
2 将堆顶元素和最后一个位置i的元素交换并调整0…i-1元素为新堆。
3 继续第2步直到堆顶元素就是最后一个元素的时候结束。
/**
* 堆排序
* @param src
*/
public static void headSort(int src[]){
int third=0;
//因为叶子节点均满足堆条件,所以从src.length/2位置开始
for(int i=src.length/2-1;i>=0;i--){//把src[1…src.length]建成大顶堆
heapAdjust(src,i,src.length-1);
}
for(int i=src.length-1;i>0;i--){//将堆顶记录和src[i]交换,并将src[0…i-1]重新调整为堆结构
third=src[0];
src[0]=src[i];
src[i]=third;
heapAdjust(src,0,i-1);
}
}
//在除了s位置均满足堆条件的序列src[s…m]上将s插入合适的位置形成堆
private static void heapAdjust(int src[],int s,int m){
//src[s…m]除src[s]之外均满足堆的定义
//本函数调整src[s]的位置,使src[s…m]
//变成一个大顶堆
int rc=src[s];
for(int j=2*s+1;j<=m;j=j*2+1){
if(j<m && src[j]<src[j+1]){
//j<m保证有右子节点
j++; //j为较大记录的下标
}
if(rc>=src[j]){break;}//third应该在位置s上
src[s]=src[j];s=j;
}
src[s]=rc; //插入
}
归并排序
2-路归并排序
/**
* 2-路归并排序的递归表示:
* 思想是平分序列从小到大归并
* 而递归的时候表示为自顶向下递归直到s==t
*/
public static void mergerSort(int src[]){2-12
mSort(src,0,src.length-1);
}
private static void mSort(int src[],int s,int t){
int m;
//将src[s…t]归并排序为有序的
if(s<t){
m=(s+t)/2; //平分
mSort(src,s,m); //递归的归并前半部分
mSort(src,m+1,t);
merge(src,s,m,t);
}
}
private static void merge(int src[],int i,int m,int n){
//将有序的src[i…m]和src[m+1…n]归并为有序的tr[i…n]
int tr[]=new int[n+1];
int k=i,j=m+1,low=i;
while(i<=m && j<=n){//将src记录由小到大归并入tr
if(src[i] <= src[j]){tr[k++]=src[i++];}
else tr[k++]=src[j++];
}
//将剩余的放入数组
while(j<=n) tr[k++]=src[j++];
while(i<=m) tr[k++]=src[i++];
//将结果拷贝回
for(k=low;k <= n;k++){src[k]=tr[k];}
}
基数排序
- 大小: 15.1 KB
- 大小: 10.8 KB
- 大小: 23.5 KB
- 大小: 43.8 KB
- 大小: 5.3 KB
- 大小: 32.9 KB
分享到:
相关推荐
C语言学习历程(待续中……)
i2 Analyst’s Notebook,已在98个国家2000多个组织中上万的用户在使用。i2 Analyst’Notebook为高效链接和时间进程分析提供了最适宜的条件。事实上,i2 Analyst’Notebook是全球同类分析软件的标准,也是...待续……
stm32入门教程,待续中,使用最好的开发软件IAR为教学软件,非常不错,待续中……
stm32入门教程,待续中,使用最好的开发软件IAR为教学软件,非常不错,待续中……
stm32入门教程,待续中,使用最好的开发软件IAR为教学软件,非常不错,待续中……
stm32入门教程,待续中,使用最好的开发软件IAR为教学软件,非常不错,待续中……
stm32入门教程,待续中,使用最好的开发软件IAR为教学软件,非常不错,待续中……
stm32入门教程,待续中,使用最好的开发软件IAR为教学软件,非常不错,待续中……
stm32入门教程,待续中,使用最好的开发软件IAR为教学软件,非常不错,待续中……
stm32入门教程,待续中,使用最好的开发软件IAR为教学软件,非常不错,待续中……
标题“网页代码很多很有意思真的很……”虽然未完待续,但足以激发我们对网页编程的好奇心。描述中提到,“使用html编写的网页,很值得去参考,大家一定考看啊!”这无疑强调了学习HTML的价值和乐趣。 HTML允许我们...
有效的括号未完待续……《数据结构与算法》数据结构与算法概述数据结构之线性表数据结构之栈与队列数据结构之树与二叉树数据结构与算法之查找数据结构之B树与B+树数据结构与算法之字符串匹配数据结构与算法之排序...
校友系统不只是一套软件系统,而是一整套“互联网+校友”的解决方案。校友系统通过帮助院校搭建校友互动平台和校友管理系统,拓展院校在校友服务方面的效率和范围,帮助院校提升校友工作信息化水平。...未完待续……
9--[小黑点的旅行(未完待续)].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码9--[小黑点的旅行(未完待续)].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码9--[小黑点的旅行(未完待续)].zip...
Collections是工具类,提供了一系列静态方法,用于对集合进行操作,如排序、查找、同步控制等。 6. **assert**: assert用于在开发和测试阶段进行断言,确保程序的某些条件始终为真。在生产环境中,通常会关闭...
扬声器作为将电信号转换成声音信号的电声转换器件,其内部的力学振动特性对声音的还原质量有着决定性的影响。要深入理解扬声器的工作原理和设计优化,就需要对扬声器单元的力学振动特性进行精确测量和分析。本文件...
"android播放器未完待续"这个标题暗示我们将探讨如何在Android系统中构建一个功能完善的音乐播放器,以及可能遇到的问题和解决方案。让我们深入研究一下。 首先,Android音乐播放器的基础是媒体库服务。Android提供...
通过包,我们可以隐藏内部实现细节,只暴露必要的接口,增加代码的可维护性和安全性。 在实际开发中,PL/SQL还常常与Oracle的其他特性相结合,如触发器(TRIGGER),它可以自动响应特定的数据库事件;索引(INDEX)...
"C++课件前半部待续!"这个标题表明这是一系列关于C++语言的教学材料,主要涵盖了C++的基础部分,并且课程还没有完全结束,后续可能还有更多内容。 描述中提到,这些课件适合初学者,易于理解,适合喜欢通过课件...
kotlin语法部分整理完成、kotlin android开放应用待续