1、冒泡排序
基本原理:1、比较相邻元素。第一个比第二个大,交换两个。2、从第一组相邻元素到结尾最后一对,针对以上步骤重复,除了最后一个。
代码:
public static void bubbleSort(int arr[]) {
for(int i =0 ; i<arr.length-1 ; i++) {
for(int j=0 ; j<arr.length-1-i ; j++) {
if(arr[j]>arr[j+1]) {
int temp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
2、快速排序
基本原理:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
代码:
public static int[] qsort(int arr[],int start,int end) {
int pivot = arr[start];
int i = start;
int j = end;
while (i<j) {
while ((i<j)&&(arr[j]>pivot)) {
j--;
}
while ((i<j)&&(arr[i]<pivot)) {
i++;
}
if ((arr[i]==arr[j])&&(i<j)) {
i++;
} else {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
if (i-1>start) arr=qsort(arr,start,i-1);
if (j+1<end) arr=qsort(arr,j+1,end);
return (arr);
}
public static void main(String[] args) {
int arr[] = new int[]{3,3,3,7,9,122344,4656,34,34,4656,5,6,7,8,9,343,57765,23,12321};
int len = arr.length-1;
arr=qsort(arr,0,len);
for (int i:arr) {
System.out.print(i+"\t");
}
}
/*//方式二*/
更高效点的代码:(TextendsComparable和SortUtil都是自己封装的类,里面重写和实现了compareTo和swap方法)
public <TextendsComparable<?superT>>
T[] quickSort(T[] targetArr,int start,int end)
{
inti=start+1,j=end;
T key=targetArr[start];
SortUtil<T> sUtil=new SortUtil<T>();
if(start==end)return(targetArr);
/*从i++和j--两个方向搜索不满足条件的值并交换
*
*条件为:i++方向小于key,j--方向大于key
*/
while(true)
{
while(targetArr[j].compareTo(key)>0)j--;
while(targetArr[i].compareTo(key)<0&&i<j)i++;
if(i>=j)break;
sUtil.swap(targetArr,i,j);
if(targetArr[i]==key)
{
j--;
}else{
i++;
}
}
/*关键数据放到‘中间’*/
sUtil.swap(targetArr,start,j);
if(start<i-1)
{
this.quickSort(targetArr,start,i-1);
}
if(j+1<end)
{
this.quickSort(targetArr,j+1,end);
}
returntargetArr;
}
/*//方式三:减少交换次数,提高效率/*/
private<TextendsComparable<?superT>>
voidquickSort(T[]targetArr,intstart,intend)
{
inti=start,j=end;
Tkey=targetArr[start];
while(i<j)
{
/*按j--方向遍历目标数组,直到比key小的值为止*/
while(j>i&&targetArr[j].compareTo(key)>=0)
{
j--;
}
if(i<j)
{
/*targetArr[i]已经保存在key中,可将后面的数填入*/
targetArr[i]=targetArr[j];
i++;
}
/*按i++方向遍历目标数组,直到比key大的值为止*/
while(i<j&&targetArr[i].compareTo(key)<=0)
/*此处一定要小于等于零,假设数组之内有一亿个1,0交替出现的话,而key的值又恰巧是1的话,那么这个小于等于的作用就会使下面的if语句少执行一亿次。*/
{
i++;
}
if(i<j)
{
/*targetArr[j]已保存在targetArr[i]中,可将前面的值填入*/
targetArr[j]=targetArr[i];
j--;
}
}
/*此时i==j*/
targetArr[i]=key;//应加判断
/*递归调用,把key前面的完成排序*/
this.quickSort(targetArr,start,i-1);
/*递归调用,把key后面的完成排序*/
this.quickSort(targetArr,j+1,end);
//两个递归应加判断
}
3、希尔排序
基本原理:希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
代码:
public static void main(String[] args){
int[] array={49,38,65,97,76,13,27,49,78,34,12,64,1};
System.out.println("排序之前:");
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
//希尔排序
int gap = array.length;
while (true) {
gap /= 2; //增量每次减半
for (int i = 0; i < gap; i++) {
for (int j = i + gap; j < array.length; j += gap) {//这个循环里其实就是一个插入排序
int temp = array[j];
int k = j - gap;
while (k >= 0 && array[k] > temp) {
array[k + gap] = array[k];
k -= gap;
}
array[k + gap] = temp;
}
}
if (gap == 1)
break;
}
System.out.println();
System.out.println("排序之后:");
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
}
4、选择排序
基本原理:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
代码:
public class SelectSort {
public static void main(String[] args) {
//模拟数据
int[] array = {52,63,14,59,68,35,8,67,45,99};
System.out.println("原数组:");
for (int i : array) {
System.out.print(i+" ");
}
System.out.println();
selectSort(array);
System.out.println("排序后:");
for (int i : array) {
System.out.print(i+" ");
}
}
public static void selectSort(int[] arr){
for(int i = 0; i < arr.length-1; i++){
int min = i;
for(int j = i+1; j <arr.length ;j++){
if(arr[j]<arr[min]){
min = j;
}
}
if(min!=i){
swap(arr, i, min);
}
}
}
//完成数组两元素间交换
public static void swap(int[] arr,int a,int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}