数据结构与算法–排序(java版)
一、冒泡排序
构造方法:
Bubblle( ):创建Bubble对象
成员方法:
1.public static void sort(Comparable[ ] a):
对数组内的元素进行排序
2.private static void boolean greater(Comparable v,Comparable w):
判断v是否大于w
3.private static void exch(Comparable[ ] a,int i,int j):
交换a数组中,索引i和索引j处的值
代码实现
public class Bubble {
public static void sort(Comparable[] a){
for(int i=a.length-1;i>0;i--){
for(int j=0;j<i;j++){
//比较索引j和索引j+1的值
if(greater(a[j],a[j+1])){
exch(a,j,j+1);
}
}
}
}
private static boolean greater(Comparable v,Comparable w){
return v.compareTo(w)>0;
}
private static void exch(Comparable[] a,int i,int j){
Comparable temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
测试
import java.util.Arrays;
public class BubbleTest {
public static void main(String[] args) {
Integer[] arr={4,5,6,1,2,3};
Bubble.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
排序结果展示
初始数组为{4,5,6,1,2,3}
排序后的结果如下:
图片:
二、选择排序
构造方法:
Selection( ):创建Selection对象
成员方法:
1.public static void sort(Comparable[ ] a):
对数组内元素进行排序
2.private static void greater(Comparable v, Comparable w):
判断v是否大于w
3.private static void exch(Comparable[ ] a,int i,int j):
交换a数组中,索引i和索引j的值
代码实现
public class Selection {
public static void sort(Comparable[] a){
for(int i=0;i<a.length-1;i++){
//定义一个变量,记录最小元素所在索引,默认为参与选择排序的第一个元素所在位置
int minIndex=i;
for (int j=i+1;j<a.length;j++){
//需要比较最小索引minIndex处的值和索引处的值;
if(greater(a[minIndex],a[j])){
minIndex=j;
}
}
//交换最小元素所在索引minIndex处的值和索引i处的值
exch(a,i,minIndex);
}
}
public static boolean greater(Comparable v,Comparable w){
return v.compareTo(w)>0;
}
public static void exch(Comparable[] a,int i,int j){
Comparable temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
测试
import java.util.Arrays;
public class SelectionTest {
public static void main(String[] args) {
Integer[] a={4,6,8,7,9,2,10,1};
Selection.sort(a);
System.out.println(Arrays.toString(a));
}
}
排序结果展示
初始数组为{4,6,8,7,9,2,10,1}
排序后的结果如下:
图片:
三、插入排序
构造方法:
Insertion( ):创建insertion对象
成员方法:
1.public static void sort(Comparable[ ] a):
对数组内元素进行排序
2.private static void greater(Comparable v, Comparable w):
判断v是否大于w
3.private static void exch(Comparable[ ] a,int i,int j):
交换a数组中,索引i和索引j的值
代码实现
public class Insertion {
//插入排序
public static void sort(Comparable[] a){
for (int i=1;i<a.length;i++){
for (int j=i;j>0;j--){
//比较索引j处的值和索引j-1处的值,如果索引j-1处的值比索引j处的值大,则交换数据。
if(greater(a[j-1],a[j])){
exch(a,j-1,j);
}else {
break;
}
}
}
}
private static boolean greater(Comparable v,Comparable w){
return v.compareTo(w)>0;
}
private static void exch(Comparable[] a,int i,int j){
Comparable temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
测试
import java.util.Arrays;
public class InsertionTest {
public static void main(String[] args) {
Integer[] a={4,3,2,10,12,1,5,6};
Insertion.sort(a);
System.out.println(Arrays.toString(a));
}
}
排序结果展示
初始数组为{4,3,2,10,12,1,5,6}
排序后的结果如下:
图片:
四、希尔排序
构造方法:
Shell( ):创建Shell对象
成员方法:
1.public static void sort(Comparable[ ] a):
对数组内元素进行排序
2.private static void greater(Comparable v, Comparable w):
判断v是否大于w
3.private static void exch(Comparable[ ] a,int i,int j):
交换a数组中,索引i和索引j的值
代码实现
public class Shell {
public static void sort(Comparable[] a){
//根据数组a的长度确定增长量h的值
int h=1;
while (h<a.length/2){
h=2*h+1;
}
while (h>=1){
//排序
//找到代插入的元素
for (int i=h;i<a.length;i++){
for (int j=i;j>=h;j-=h){
//待插入的元素是a[j],比较a[j]和a[j-h]
if(greater(a[j-h],a[j])){
//交换元素
exch(a,j-h,j);
}else {
//待插入元素元素已经找到了正确的位置
break;
}
}
}
//把待插入的元素插到有序数列中
//减小h的值
h=h/2;
}
}
private static boolean greater(Comparable v,Comparable w){
return v.compareTo(w)>0;
}
private static void exch(Comparable[] a,int i,int j){
Comparable temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
测试
import java.util.Arrays;
public class ShellTest {
public static void main(String[] args) {
Integer[] a={9,1,2,5,7,4,8,6,3,5};
Shell.sort(a);
System.out.println(Arrays.toString(a));
}
}
五、归并排序
构造方法:
Merge( ):创建Merge对象
成员方法:
1.public static void sort(Comparable[ ] a):
对数组内元素进行排序
2.private static void sort(Comparable[ ] a,int lo,int hi):
对数组a中从索引o到索引hi之间的元素进行排序
==3.private static void merge(Comparable[ ] a,int lo,int mid,int hi): ==
从索引lo到索引mid为一个子组,从索引mid+1到索引hi为另一个子组,把数组a中的两个子组的数据合并成一个有序的组。
4.private static void greater(Comparable v, Comparable w):
判断v是否大于w
5.private static void exch(Comparable[ ] a,int i,int j):
交换a数组中,索引i和索引j的值
代码实现
public class Merge {
private static Comparable[] assist;
//归并排序
public static void sort(Comparable[] a){
//初始化辅助数组assist
assist=new Comparable[a.length];
//定义一个lo变量和hi变量,分别记录数组中最小的索引和最大的索引
int lo=0;
int hi=a.length-1;
//调用sort重载方法完成数组a中,从索引lo到索引hi的元素的排序
sort(a,lo,hi);
}
private static void sort(Comparable[] a,int lo,int hi){
//做安全性校验
if(hi<=lo){
return;
}
//对lo和hi之间的数据进行分组,分为两个组
int mid=lo+(hi-lo)/2;
//分别对每一组数据进行排序
sort(a,lo,mid);
sort(a,mid+1,hi);
//再把两个组中的数据进行归并
merge(a,lo,mid,hi);
}
private static void merge(Comparable[] a,int lo,int mid,int hi){
//定义三个指针
int i=lo;
int p1=lo;
int p2=mid+1;
//遍历移动p1指针和p2指针,比较对应索引处的值,找出最小的那个,放到辅助数组的对应索引处
while(p1<=mid && p2<=hi){
//比较对于索引处的值
if(less(a[p1],a[p2])){
assist[i++]=a[p2++];
}else {
assist[i++]=a[p1++];
}
}
//遍历,如果p1的指针没有走完,那么顺序移动p1指针,把对应的元素放到辅助数组的对应索引处
while (p1<=mid){
assist[i++]=a[p1++];
}
//遍历,如果p2的指针没有走完,那么顺序移动p2指针,把对应的元素放到辅助数组的对应索引处
while ((p2<=hi)){
assist[i++]=a[p2++];
}
//把辅助数组中的元素拷贝到原数组中
for(int index=lo;index<=hi;index++){
a[index]=assist[index];
}
}
private static boolean less(Comparable v,Comparable w){
return v.compareTo(w)>0;
}
private static void exch(Comparable[] a,int i,int j){
Comparable temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
测试
import java.util.Arrays;
public class MergeTest {
public static void main(String[] args) {
Integer[] a={8,4,5,7,1,3,6,2};
Merge.sort(a);
System.out.println(Arrays.toString(a));
}
}
排序结果展示
初始数组为{8,4,5,7,1,3,6,2}
排序后的结果如下:
图片:
六、快速排序
构造方法:
Quick( ):创建Quick对象
成员方法:
1.public static void sort(Comparable[ ] a):
对数组内元素进行排序
2.private static void sort(Comparable[ ] a,int lo,int hi):
对数组a中从索引o到索引hi之间的元素进行排序
3.private static int partition(Comparable[ ] a,int lo,int hi):
对数组a中,从索引lo到索引hi之间的元素进行分组,并返回分组界限对应的索引
4.private static void greater(Comparable v, Comparable w):
判断v是否大于w
5.private static void exch(Comparable[ ] a,int i,int j):
交换a数组中,索引i和索引j的值
代码实现
public class Quick {
public static void sort(Comparable[] a){
int lo=0;
int hi=a.length-1;
sort(a,lo,hi);
}
private static void sort(Comparable[] a,int lo,int hi){
//安全性校验
if(hi<=lo){
return;
}
//需要对数组中lo索引和hi索引处的元素进行分组(左子组和右子组)
int partition=partition(a,lo,hi);//返回的是分组的分界值所在的索引,分界值位置变换后的索引
//让左子组有序
sort(a,lo,partition-1);
//让有子组有序
sort(a,partition+1,hi);
}
public static int partition(Comparable[] a,int lo,int hi){
//确定分界值
Comparable key=a[lo];
//定义两个指针,分别指向待切分元素的最小索引和最大索引处的下一个位置
int left=lo;
int right=hi+1;
//切分
while (true){
//先从右往左扫描,移动right指针,找到一个比分界值小的元素,停止
while (less(key,a[--right])){
if(right==lo){
break;
}
}
//在从左往右扫描,移动left指针,找到一个比分界值小的元素,停止
while (less(a[++left],key)){
if(left==hi){
break;
}
}
//判断left>=right,如果是,则证明元素扫描完毕,结束循环;如果不是交换元素即可
if (left>=right){
break;
}else {
exch(a,left,right);
}
}
//交换分界值
exch(a,lo,right);
return right;
}
private static boolean less(Comparable v,Comparable w){
return v.compareTo(w)<0;
}
private static void exch(Comparable[] a,int i,int j){
Comparable temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
测试
import java.util.Arrays;
public class QuickTest {
public static void main(String[] args) {
Integer[] a={6,1,2,7,9,3,4,5,8};
Quick.sort(a);
System.out.println(Arrays.toString(a));
}
}
排序结果展示
初始数组为{6,1,2,7,9,3,4,5,8}
排序后的结果如下:
图片: