做过几次各大IT公司的实习生招聘笔试题,发现数据结构还是很重要的,其中排序问题总是会出现在试题上,所以对几种常见的排序方法总结下。
其实排序可分为两大类:内部排序和外部排序
内部排序:指需排序的记录存放在计算机随机存储器中进行的排序过程,也就是小数量的数据排序,像冒泡排序,选择排序等就是内部排序;
外部排序:指需排序的记录数量很大,以致内存一次不能容纳全部记录,在排序过程中需对外存进行访问的排序过程;这种我暂时没怎么接触过,不多说了;
下面是几种常见的部内排序方法:
1. 直接插入排序
每次从无序表中抽出一个数插入到有序表中,使得表仍然有序,第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程,整个过程如下:
假设序列为49 38 65 97 76 13 27
【初始关键字】 ( 49 ) 38 65 97 13 27
i=2 (38) ( 38 49 ) 65 97 13 27
i=3 (65) ( 38 49 65 ) 97 13 27
i=4 (97) ( 38 49 65 97 ) 13 27
i=5 (13) ( 13 38 49 65 97 ) 27
i=5 (27) ( 13 27 38 49 65 97 )
监视哨(保存当前待比较的数值)temp
Java代码实现:
int[] text(int[] a ){
for (int i = 1; i < a.length; i++) {
int temp = a[i];
for (int j = i; j > 0 && temp < a[j-1]; j--) {
a[j] = a[j - 1];
}
a[j] = temp;
}
return a;
}
2.希尔排序
又称缩小增量排序,其基本思想是:先将整个待排序的记录序列分割成若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序;
就是先取一个小于n(整个记录的长度)的整数t1作为第一个增量,把文件的全部记录分成t1个组。所有距离为t1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量t2<t1重复上述的分组和排序,直至所取的增量ti=1(ti<ti-l<…<t2<t1),即所有记录放在同一组中进行直接插入排序为止;
如果记录的量大且一组内的记录相隔距离远,那么就可以省去多次数据交换,这就是对直接插入排序的改进之处。示例如下:
假设序列为:49 38 65 97 76 13 27 49 55 04
增量可取: 5 , 3 , 1
【初始关键字】 49 38 65 97 76 13 27 49 55 04
先分成5组:(49 13) (38 27) (65 49) (97 55) (76 04)
每一组进行直接插入排序后:13 27 49 55 04 49 38 65 97 76(第一趟排序结果)
然后分成3组:(13 55 38 76) (27 04 65) (49 49 97)
每一组进行直接插入排序后:13 04 49 38 27 49 55 65 97 76(第二趟排序结果)
再分成1组(对整个序列排序) (13 04 49 38 27 49 55 65 97 76)
进行直接插入排序后:04 13 27 38 49 49 55 65 76 97(第三趟排序结果)
Java代码实现:
int [] ShellSort(int[] a) {
int Temp; // 暂存变量
int DataLength; // 分割集合的间隔长度
int Pointer; // 进行处理的位置
DataLength = a.length / 2; // 初始集合间隔长度
while (DataLength != 0) // 数列仍可进行分割
{ // 对各个集合进行处理
for (int j = DataLength; j < a.length; j++) {
Temp = a[j]; // 暂存Data[j]的值,待交换值时用
Pointer = j - DataLength; // 计算进行处理的位置
// 进行集合内数值的比较与交换值
while (Temp < a[Pointer] && Pointer >= 0 && Pointer < a.length) {
a[Pointer + DataLength] = a[Pointer];
// 计算下一个欲进行处理的位置
Pointer = Pointer - DataLength;
if (Pointer < 0 || Pointer >= Index)
break;
}
// 与最后的数值交换
a[Pointer + DataLength] = Temp;
DataLength = DataLength / 2; // 计算下次分割的间隔长度
}
return a;
}
3.冒泡排序
冒泡排序的过程很简单,首先将第一个数和第二个数进行比较,如果是逆序的,就将两个数交换,然后比较第二个数和第三个数,依次类推,直到第n-1个数和第n个数据进行比较完为止,然后进行延续二趟排序,对前n-1个数进行同类操作,直到没有数可比;
假设序列为: 49 38 65 97 76 13 27 49
第一趟排序:38 49 65 76 13 27 49 97
第二趟排序:38 49 65 13 27 49 76
第三趟排序:38 49 13 27 49 65
第四趟排序:38 13 27 49 49
第五趟排序:13 27 38 49
第六趟排序:13 27 38
从上面的排序过程可以看到:大的数一个个往下沉,小的数的就向上浮,跟这个排序方法的名字很贴切。
Java代码实现:
int sort (int[] a){
for(int j=1;j<=a.length;j++){
for(int i=0;i<a.length-j;i++){
if(a[i]>a[i+1]){
int temp;
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
return a;
}
为了提高效率,可以设置一个是否继续比较下去的标志,因为如果数列的排列顺序就是所要求的顺序,那就没必要一个个往下比了,比如:当一趟排序中没有发生数据交换,就可以提前终止。
4.快速排序
快速排序是对冒泡排序的一种改进,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列;
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
一趟快速排序的算法是:
1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];
3)从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于key的值A[J],并与A[I]交换;
4)从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于key的A[I],与A[J]交换;
5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束)
过程可如下图表示:
上面是完成一趟排序的过程,整个排序过程可描述如下:
初始状态 (49 38 65 97 76 13 27 49)
一次划分之后 ( 27 38 13 ) 49 (76 97 65 49)
分别进行快速排序 (13)27 (38)
结束 结束 ( 49 65 ) 76 ( 97 )
49 ( 65 ) 76 结束
结束
有序序列 ( 13 27 38 49 49 65 76 97 )
Java代码实现:
int[] sort(int[] data, int low, int high) {
// 枢纽元,一般以第一个元素为基准进行划分
int i = low;
int j = high;
if (low < high) {
// 从数组两端交替地向中间扫描
int pivotKey = data[low];
// 进行扫描的指针i,j;i从左边开始,j从右边开始
while (i < j) {
while (i < j && a[j]>=pivotkey) {
j--;
}// end while
if (i < j) {
// 比枢纽元素小的移动到左边
data[i] = data[j];
i++;
}// end if
while (i < j && a[i]<=pivotkey) {
i++;
}// end while
if (i < j) {
// 比枢纽元素大的移动到右边
data[j] = data[i];
j--;
}// end if
}// end while
// 枢纽元素移动到正确位置
data[i] = pivotKey;
// 前半个子表递归排序
sort(data, low, i - 1);
// 后半个子表递归排序
sort(data, i + 1, high);
}// end if
return a;
}// end sort
5.简单选择排序
其基本思想是:在每一趟排序中将n-i+1(i=1,2,…,n-1)个记录中选取最小的记录和有序序列中第i个记录交换,个人觉得这种排序方法跟冒泡排序很像,比如从小到大排序,冒泡是将大的数一个一个往下沉,而简单选择排序是将小的数一个个往上冒;
Java代码实现:
int[] sort(int[] data) {
int len = data.length;
for (int i = 0; i < len; i++) {
int position = i;
for (int j = i + 1; j < len; j++) {
if (data[position]>data[j])) {
position = j;
}
}
Int temp = data[i];
data[i] = data[position];
data[position] = temp;
}
}
分享到:
相关推荐
本篇文章将详细解析Java中常见的排序方法,结合"javaeye 收集的java排序小结"资料,旨在帮助读者理解和掌握这些排序算法。 1. 冒泡排序(Bubble Sort) 冒泡排序是最简单的排序算法之一,通过重复遍历数组,比较...
这篇博客“常用排序算法小结(附Java实现)”提供了一种深入理解并掌握常见排序算法的途径,尤其对于Java开发者来说非常实用。文章可能涵盖了如冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序等多种经典...
### 各种排序算法小结 #### 一、引言 排序算法是在计算机科学中非常基础且常用的一类算法。由于在实际应用中往往需要处理大量数据,因此对排序算法的效率有着较高要求。通常,我们会关注算法的时间复杂度来评估其...
排序算法是计算机科学中基础且重要的概念,它们用于组织和整理数据,使得数据按照特定顺序...在大多数情况下,快速排序、归并排序和堆排序是常用的选择,而插入排序、冒泡排序等则更适合小规模或特定条件下的排序需求。
在高级语言的执行速度上,c是最快的,c++其次,而java和c#是最后的。Java和c#流行,主要的一个原因是可以跨平台。
在**字符串练习一**中,我们展示了如何使用`compareTo`方法对字符串数组进行排序。`compareTo`是`String`类的一个方法,它根据Unicode值比较两个字符串。如果第一个字符串大于第二个字符串,`compareTo`返回正整数;...
`sort(compareFunction)`方法可以接受一个比较函数作为参数,用于控制排序逻辑。如果没有提供比较函数,则按照字符编码的顺序排序。 3. **splice()方法**:提供了删除、插入、替换数组元素的功能。`splice(start, ...
### 排序算法小结讲解+源码 #### 一、引言 排序算法作为计算机科学中的基础且常用算法,在实际应用中具有重要意义。随着数据量的不断增加,对排序算法的效率提出了更高要求。本文将从简单排序算法出发,逐步过渡到...
它的基本思想是采用分治法,通过选取一个基准值,将数组分为两部分,一部分的所有元素都比基准值小,另一部分的所有元素都比基准值大,然后再分别对这两部分进行快速排序,直到整个序列有序。代码中给出的快速排序...
JavaScript中的引用类型主要包括Object、Array、Date和RegExp等,这些类型在编程中有着广泛的应用,以下是对它们常用操作方法的详细解析。 **Object类型** 在JavaScript中,Object是最基础的数据结构,可以用来创建...
Java数组常用排序算法实例小结 Java数组常用排序算法是每个Java开发者都需要掌握的基本技能,本文将通过实例形式总结分析Java数组常用的四种排序算法,分别是冒泡排序、数组递增排序、快速排序及选择排序。 一、...
根据提供的文件信息,我们可以总结出一系列关于SQL Server的常用语句及操作方法。这些语句在数据库管理和数据操作中非常实用。以下是对标题、描述以及部分文件内容中的关键知识点进行详细解析: ### 1. 创建表 ####...
PHP提供了多种函数来实现这一需求,本文主要介绍两种常用的方法:使用array_multisort函数和自定义排序函数array_sort方法,分别对多维数组按照指定键值进行排序。 首先,array_multisort函数是一个强大的排序工具...
这些方法以及相关的排序算法、遍历算法、数学运算、数据结构和查找算法等都是JavaScript中不可或缺的一部分,它们共同构成了JavaScript数组操作的完整体系。对于希望深入学习JavaScript的开发者来说,研究和实践这些...
在JavaScript中,Array对象是最常用的内置对象之一,它提供了存储一系列值的能力。有多种方式创建数组: 1. 使用`new Array()`构造函数,可以为空数组、指定数组长度或者传入初始元素。 2. 使用字面量语法`[]`,...
6. 数组常用方法 本文还提到了一些常见的数组操作方法,这些方法对于理解和操作数组非常有帮助。包括但不限于: - slice():提取数组的一部分并返回,不改变原数组。 - concat():用于合并两个或多个数组,返回新...
Java数组高级算法与Arrays类常见操作小结【排序、查找】 Java数组高级算法与Arrays类常见操作小结是Java数组高级算法的核心内容之一。本文主要介绍了Java数组高级算法与Arrays类常见操作,结合实例形式总结分析了...
下面是对星外系统IIS日志分析常用的一些命令的小结: 1. **查询特定IP访问特定网站页面的次数** 这个命令用于统计一个特定IP地址访问特定网站页面的次数,并按访问次数降序排列。命令格式如下: ``` 7i24iislog....
以下将详细讲解三种常用的方法来实现这一操作。 方法一:使用`TOP`关键字与`NOT IN`子句 这种方法是通过先查询出前10条记录,然后排除这些记录,再获取接下来的20条记录。具体的SQL语句如下: ```sql SELECT TOP ...