冒泡
public void sortedList1(int[] arr) {
int tmp;
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
快速
/**
* @param arr 排列的数组
* @param left 当前排列数组片段的最左下标
* @param right 当前排列数组片段的最右下标
* @param tmp 默认右边下标先判断,则tmp取最左下标值arr[left]
*/
public void sortedList2(int[] arr, int left, int right, int tmp) {
int start = left; //记录当前需要排序数组片段起点下标
int end = right; //记录当前需要排序数组片段终止下标
int pos = 1; //1:当前由right指针判断(默认), 0:当前由left指针判断
while (left != right) {
if (pos == 1) {
if (arr[right] < tmp) {
arr[left] = arr[right]; //数组左端下标赋值
left++; //左下标往左移一位
pos = 0; //切换为left指针判断
} else {
//右下标继续移动
right--;
}
} else {
if (arr[left] > tmp) {
arr[right] = arr[left]; //数组右端下标赋值
right--; //右下标往右移一位
pos = 1; //切换为right指针判断
} else {
//左下标继续移动
left++;
}
}
}
// 跳出循环,此时left、right指向同一下标,left = right,取哪个都行
arr[left] = tmp; //已经定位tmp值的位置,即下标为left(right)
// 以left(right)下标作为分割点,进行下面的判断
if (left - start > 1) {
// 左边数组片段长度大于1,继续快排
sortedList2(arr, start, left - 1, arr[start]);
}
if (end - left > 1) {
// 右边数组片段长度大于1,继续快排
sortedList2(arr, left + 1, end, arr[left + 1]);
}
}
选择
// 选择排序,改进了冒泡,减少了交换的次数
public void sortedList3(int[] arr) {
int minIdx; //记录最小值下标
int tmp; //交换暂存变量
for (int i = 0; i < arr.length; i++) {
minIdx = i; // 默认取到的第一个为最小值
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIdx]) {
minIdx = j; //重新记录最小值下标
}
}
if (minIdx != i) {
//最小值不是第一个,则交换
tmp = arr[i];
arr[i] = arr[minIdx];
arr[minIdx] = tmp;
}
}
}
插入
public void sortedList4(int[] arr) {
int tmp;
for (int i = 1; i < arr.length; i++) {
tmp = arr[i]; //需要插入的值
for (int k = i; k > 0; k--) {
if(arr[k-1] > tmp){
arr[k] = arr[k-1]; //向后移动一位
if (k==1) //此时tmp是最小值,已经移动到了arr[1],且此时arr[0]=arr[1]
arr[k-1] = tmp; // arr[0]赋值
}else if (arr[k-1] < tmp){
if (k != i) //如果k == i 此时的tmp刚好比前面的值都大,无需移动,直接跳出循环
arr[k] = tmp;
break;
}
}
}
}