以下排序默认排序效果是从小到大,待排序序列:3,4,63,4,-9,0,1,32,-2
1.冒泡排序
基本思想:依次交换相邻两个元素,使得大的数据往下沉(或小的数据往上附浮)
第一步:比较相邻的两个元素,如果前者比后者大,则交换两元素。否则,不交换。
第二步:重复第一步直到最后两个元素比较完成,此时,最大的元素已经在最后面了,此趟排序完成。
第三步:去除最后元素,重复上述两步,对最后元素之前的数据进行排序。
第四步:每趟排序完成后,大的数据会忘下沉,也就是需要排序的数据会越来越少,直到没有任何一对数据需要排序,排序成功
排序过程示例:
代码示例:
public void bullle(int[] array) {
//双层循环,第一层控制需要排序的趟数
for(int i=0; i<array.length-1; i++) {
//第二层,对第一个直到array.length-i-1的数据排序
for(int j=0; j<array.length-i-1; j++) {
//前者大于后者,交换元素
if(array[j]>array[j+1]) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
2.鸡尾酒排序
基本思想:鸡尾酒排序法相当于双向冒泡排序,在鸡尾酒排序中,在从左向右的方向上,使大的数据往下沉,在回来也就是从右往左的方向上,使小的数据往上浮。
过程示例:
代码示例:
public void cocktailSort(int[] array) {
int temp;
for(int k=0; k<array.length/2; k++) {
//使大的数据往下沉
for(int i=k; i<array.length-k-1; i++) {
if(array[i]>array[i+1]) {
temp = array[i];
array[i] = array[i+1];
array[i+1] = temp;
}
}
//使小的数据往上浮
for(int j=array.length-2-k; j>k; j--) {
if(array[j]<array[j-1]) {
temp = array[j];
array[j] = array[j-1];
array[j-1] = temp;
}
}
}
}
3.快速排序
基本思想:通过一趟排序,使得排序序列分为两部分,一部分的所有数据都小于另一部分,然后在按此方法分别对两部分进行排序,整个排序过程可用递归进行
第一步:选取一个基准值(一般为待排序列的首元素),并记录,使得 i , j 分别指向首元素和最后一个元素
第二步:从右册开始,比较 j 指向元素和基准值的大小,如果大于,j 向前移动一个元素,直到找到一个比基准值小的元素,停止 j 的移动。
此时, 将 j 所指向的元素赋值给 i 所指向的元素,并让 i 向后移动 一 个元素。
第三步:从左侧开始,比较 i 指向元素和基准值的大小,如果小于,i 向后移动一个元素,直到找到一个比基准值大的元素,停止 i 的移动。
此时, 将 i 所指向的元素赋值给 j 所指向的元素,并让 j 向前移动 一 个元素。
第四步:重复上述步骤,知道 i 和 j 指向同一个元素,并将基准值赋值给i 和 j所指向的元素。
此时,序列已经被基准值分为两部分,左侧所有元素小于基准值,右侧所有的元素大于基准值
第五步:使用相同方法,对基准值两侧的序列分别进行排序
排序过程示例:
代码示例:
private void quickSort(int[] array, int start, int end) {
int i = start, j = end;
int temp = array[start];//记录基准值
while(i<j) {
//从右侧开始,找到第一个小于基准值的元素
while(i<j && array[j]>temp) {
j--;
}
//将j所在位置元素赋值给i所指向的元素,并使i向后移动
if(i<j) {
array[i] = array[j];
i++;
}
//从左侧开始,找到第一个大于基准值的元素
while(i<j && array[i]<temp) {
i++;
}
//将i所在位置元素赋值给j所指向的元素,并使j向前移动
if(i<j) {
array[j] = array[i];
j--;
}
}
//当i>=j时,循环查找结束,将基准值赋值给i所在位置
array[i] = temp;
//对基准值分割的两部分进行排序
if(i-1>start) {
quickSort(array, start, i-1);
}
if(i+1<end) {
quickSort(array, i+1, end);
}
}
4.插入排序
基本思想:排序序列分为两部分,前一部分是已排序的序列,后一部分为待排序序列。
第一步:从待排序序列中选择一个元素,依次比较其和已排序序列中的元素的大小,直到找到一个比它大的元素,并将其插入到这个元素前边
第二步:重复上步,直到待排序序列中没有元素了。
排序过程示例:
代码示例:
public void InsertSort(int[] array) {
for(int i=1; i<array.length; i++) {
/*
* 第一种方法, 从前往后搜索,直到找到比它大的元素
* 然后将这个元素往后所有已排序序列中的元素向后移动
* */
// for(int j=0; j<i; j++) {
// if(array[i]<array[j]) {
// int temp = array[i];
// int k = i;
// while(k>j) {
// array[k] = array[k-1];
// k--;
// }
// array[j] = temp;
// break;
// }
// }
/*
* 第二种方法,从后往前搜索,直到找到一个比它小的元素
* 同样将这个元素往后所有已排序序列中的元素向后移动
* */
int temp = array[i];
int j = i;
if(array[j-1]>temp) {
while(j>=1 && array[j-1]>temp) {
array[j] = array[j-1];
j--;
}
}
//将这个元素赋值给相应位置
array[j] = temp;
}
}
5.选择排序
这个选择排序和插入排序看上去很像,都是从未排序的序列中选择一个元素,然后插入到已排序序列中。不过它们有很大的不同,选择排序是从待排序序列中选择
一个最小的元素,然后将这个元素插入到已排序序列的最后,这个方法的优点是,不需要频繁的在数组中移动数据,只需要两两交换即可。
基本思想: 第一步:从待排序序列中通过比较,找到最小的元素,记录其位置和值
第二步:将这个元素与待排序序列的第一个元素(也就是已排序序列最后元素的下一个元素)交换值。重复上述两步,直到所有元素已排完。
排序过程示例:
代码示例:
public void selectSort(int[] array) {
for(int i=0; i<array.length-1; i++) {
int loc = i;
int min = array[i];
//在待排序序列中找到最小的元素
for(int j=i+1; j<array.length; j++) {
if(min>array[j]) {
min = array[j];
loc = j;
}
}
if(loc != i) {
array[loc] = array[i];
array[i] = min;
}
}
}
6.归并排序
基本思想:将待排序序列分为的两部分,然后对这两部分分别排序,最后将两部分按某种方法合并。排序的过程是一个递归的过程。归并法是算法中分治法的一个典型代表。因此,归并排序也分为两部分,分的过程和治(合并)的过程。
合并使用的方法是:比较两个队列的队首元素,将小的从该队列中移除并插入到新队列的第一个位置,然后在比较两队列的首元素大小,将小的从该队列移除并将其添加到新队列上次添加的元素的后面,重复第二步知道有一个队列为空。将不为空的队列剩下所有的元素依次添加到新队列的最后。
排序过程示例:
第一次分割:{3, 4, 63, 2}{-9, 0, 1, 32, -2}
下面以分割后的第一部分为例。
第二次分割:{{3,4}{63, 2}} 第三次分割:{{{3}{4}}{{63}{2}}}
合并的过程:第一次合并:{{3,4}{2,63}} 第二次合并:{2,3,4,63}至此,第一部分已经排序完毕,第二部分排序方法相同,为{-9,-2,0,1,32}
最后将两部分合并为:{-9,-2,0,1,2,3,4,32,63}
代码示例:
private void MergeSort(int[] array, int start, int end) {
if(start == end) {
return;
}
int middle = (end - start + 1)/2 + start;
//分的过程
MergeSort(array, start, middle-1);
MergeSort(array, middle, end);
//合并的过程
merge(array, start, middle, end);
}
private void merge(int[] array, int start, int middle, int end) {
int i = start, j = middle, loc = 0;
int[] copy = new int[end-start+1];
while(i<middle && j<=end) {
if(array[i]>array[j]) {
copy[loc] = array[j];
j++;
} else {
copy[loc] = array[i];
i++;
}
loc++;
}
while(i<middle) {
copy[loc++] = array[i++];
}
while(j<=end) {
copy[loc++] = array[j++];
}
for(int k=0; k<copy.length; k++) {
array[start++] = copy[k];
}
copy = null;
}