Java中的各种排序
- 简单排序(冒泡排序、插入排序)
- 希尔排序
- 堆排序
- 归并排序
冒泡排序
冒泡排序的源码:
public static void BubbleSort(int[] arr)
{
for(int i=arr.length-1; i >= 0; i--)
{
for(int j=0; j < i; j++)
{
if(arr[j] > arr[j+1])
{
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
//冒泡排序的优化,设置一个标记flag,如果遍历一次之后发现数组已经有序,那么跳出大循环即可
public static void BubbleSort2(int[] arr)
{
for(int i=arr.length-1; i >= 0; i--)
{
int flag = 0; //flag的0代表没有交换,1代表已经交换
for(int j=0; j < i; j++)
{
if(arr[j] > arr[j+1])
{
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = 1;
System.out.println("交换一次...");
}
}
if(flag == 0)
{
break;
}
}
}
插入排序
插入排序的源码:
public static void InsertSort(int[] arr)
{
for(int i=1; i < arr.length; i++)
{
int temp = arr[i];
int j;
for(j=i-1; j >= 0 && arr[j] > temp; j--)
{
arr[j+1] = arr[j];
}
arr[j+1] = temp; //这个要注意,应该是arr[j+1]而不是arr[j]
}
}
希尔排序
特点:利用了插入排序的简单,克服了插入排序中,每次只简单交换相邻元素的缺点
步骤:先进行大间隔排序,然后进行小间隔排序,最后进行1间隔排序;从n/2间隔开始
更小间隔的排序没有破环前面排序的结果
选择排序
堆排序
堆排序其实就是堆选择排序的一种改进
归并排序
策略:分而治之
快速排序
策略:分而治之
伪码描述:
void QuickSort(ElementType[] arr, int n)
{
if(n < 2) return;
pivot = 从arr中选出一个主元;主元要选择好
将arr根据pivot分成两个独立的子集A1和A2:
n = n1 + n2 + 1;
arr = QuickSort(A1, n1) 并 pivot 并 QuickSort(A2, n2);
}
要点:
1.选主元:
经典的方法是,取头、中、尾的中位数
2.子集划分:
3.如果有元素正好等于pivot,那么有两种处理方法:
* 停下来交换 较好
* 不理它,继续移动指针
4.小规模数据的处理
当递归的数据规模充分小时,停止递归,直接调用简单排序 在程序中定义一个Cutoff的阈值
快速排序的源码:
public static void QuickSort(int[] arr, int left, int right)
{
int Cutoff = 3; //添加一个阈值
if(Cutoff <= right - left)
{
int pivot = Median3(arr, left, right);
int i = left;
int j = right - 1;
for( ; ; )
{
while(arr[++i] < pivot);
while(arr[--j] > pivot);
if(i < j)
{
Swap(arr[i], arr[j]);
}
else
{
break;
}
}
Swap(arr[i], arr[right-1]);
QuickSort(arr, left, i - 1);
QuickSort(arr, i, right);
}
else
{
InsertSort(arr);
}
}
//找出三个数的中位数
public static int Median3(int[] arr, int left, int right)
{
int mid = (left + right) / 2;
if(arr[left] > arr[mid])
{
Swap(arr[left], arr[mid]);
}
if(arr[left] > arr[right])
{
Swap(arr[left], arr[right]);
}
if(arr[mid] > arr[right])
{
Swap(arr[mid], arr[right]);
}
Swap(arr[mid], arr[right-1]); //将中间值放在right的左边
return arr[right-1];
}
//交换两个元素的位置
public static void Swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}