直接插入排序
排序思想:直接插入排序的基本思想是:n个待排序的元素由一个有序表和一个无序表组成,开始时有序表中只包含一个元素。排序过程中,每次从无序表中取出第一个元素,将其插入到有序表中的适当位置,使有序表的长度不断加长,完成排序过程。
public static void InsertSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int temp = arr[i],j=i;
for (; j > 0 && temp < arr[j - 1]; j--) {
arr[j] = arr[j - 1];
}
arr[j] = temp;
}
}
希尔排序
排序思想:先将整个待排序元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的),分别进行直接插入排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。
public static void ShellSort(int[] arr,int[] dlta) {
for (int i = 0; i < dlta.length; i++) {
for (int k = dlta[i]; k < arr.length; k++) {
int temp = arr[k],j=k;
for (; j >= dlta[i] && temp < arr[j - dlta[i]] ; j-=dlta[i]) {
arr[j] = arr[j-dlta[i]];
}
arr[j] = temp;
}
}
}
冒泡排序
排序思想:将相邻位置的关键字进行比较,若为逆序则交换之。
public static void BubbleSort(int[] arr){
boolean change=true;
for (int i = 0; i < arr.length-1&&change; i++) {
change=false;
for(int j=0;j< arr.length-i-1;++j){
if(arr[j]>arr[j+1]){
change=true;
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
快速排序
排序思想:快速排序是迄今为止所有内排序算法中速度最快的一种。其基本思想是:取待排序序列中的某个元素作为基准(一般取第一个元素),通过一趟排序,将待排元素分为左右两个子序列,左子序列元素的关键字均小于或等于基准元素的关键字,右子序列的关键字则大于基准元素的关键字,然后分别对两个子序列继续进行排序,直至整个序列有序。
public static int Partition(int[] arr,int l,int h){
int temp=arr[l],i=l,j=h;
while(i<j){
while(i<j&&arr[j]>=temp) --j;
arr[i]=arr[j];
while(i<j&&arr[i]<=temp) ++i;
arr[j]=arr[i];
}
arr[i]=temp;
return i;
}
//快速排序
public static void QuickSort(int[] arr,int l,int h){
if(l<h){
int partition = Partition(arr, l, h);
QuickSort(arr,l,partition-1);
QuickSort(arr,partition+1,h);
}
}
简单选择排序
排序思想:第一趟在n个记录中选取最小记录作为有序序列的第一个记录,第二趟在n-1个记录中选取最小记录作为有序序列的第二个记录,第i趟在n-i+1个记录中选取最小的记录作为有序序列多中的第i个记录。
public static void SimpleSelectSort(int[] arr){
for (int i = 0; i < arr.length; i++) {
int k=i;
for (int j = i+1; j < arr.length; j++) {
if(arr[j]<arr[k]){
k=j;
}
}
if(k!=i){
int temp=arr[k];
arr[k]=arr[i];
arr[i]=temp;
}
}
}
堆排序
排序思想:对一组待排序记录的关键字,首先把它们按堆的定义建成小(大)顶堆,然后输出堆顶的最小(大)关键字所代表的记录,再对剩余的关键字建堆,以便得到次小(大)的关键字,如此反复进行,直到全部关键字排成有序序列为止。
实现堆排序需要解决两个问题:
(1) 如何建堆?
(2) 输出堆顶元素后,如何将剩余元素重新调整为一个新堆?
public static void heapAdjust(int[] nums, int s, int len) {
int temp = nums[s];
int i;
for (i = 2 * s + 1; i <= len; i = i * 2 + 1) {
if (i < len && nums[i] < nums[i + 1]) i++;
if (temp >= nums[i]) break;
nums[s] = nums[i];
s = i;
}
nums[s] = temp;
}
public static void HeapSort(int[] nums, int len) {
for (int i = len / 2 - 1; i >= 0; i--) {
heapAdjust(nums, i, len - 1);
}
for (int i = 1; i < len; i++) {
int temp = nums[0];
nums[0] = nums[len - i];
nums[len - i] = temp;
heapAdjust(nums, 0, len - i - 1);
}
}
归并排序
排序思想:可将由n个记录的一个无序序列看成是由n个长度为1的有序子序列组成的序列,然后进行两两归并,得到[n/2]个长度为2或1的有序子序列,再两两归并,……,如此重复,直到最后形成包含n个记录的一个有序序列为止。这种总是反复将两个有序序列归并成一个有序序列的排序方法称为两路归并排序。
//归并排序
public static void MergeSort(int[] arr,int s,int t){
if(s<t){
int m=(s+t)/2;
MergeSort(arr,s,m);
MergeSort(arr,m+1,t);
Merge(arr,s,m,t);
}
}
private static void Merge(int[] arr, int i, int m, int n) {
int b=i;
int[] temp=new int[arr.length];
int j,k=0;
for(j=m+1;i<=m&&j<=n;++k){
if(arr[i]<arr[j]) temp[k]=arr[i++];
else temp[k]=arr[j++];
}
for(;j<=n;) temp[k++]=arr[j++];
for(;i<=m;) temp[k++]=arr[i++];
for(i=b,k=0;i<=n;) arr[i++]=temp[k++];
}
基数排序
排序思想:基数排序是一种借助多关键字排序的思想对单逻辑关键字进行排序的方法,不需要进行记录关键字间的比较。
public static void RadixSort(int[] arr) {
int max = Integer.MIN_VALUE;
for (int value : arr) {
if (value > max) {
max = value;
}
}
int maxLength = (max + "").length();
int[][] temp = new int[10][arr.length];
int[] counts = new int[10];
for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
for (int j = 0; j < arr.length; j++) {
int remainder = arr[j] / n % 10;
temp[remainder][counts[remainder]] = arr[j];
counts[remainder]++;
}
int index = 0;
for (int k = 0; k < counts.length; k++) {
if (counts[k] != 0) {
for (int l = 0; l < counts[k]; l++) {
arr[index] = temp[k][l];
index++;
}
counts[k] = 0;
}
}
}
}