1.选择排序
理解核心思想,取出一个元素,在它后面的每一位中进行比较,选择出一个最小/最大的元素,来与它交换。
代码示例
//比较
public static boolean less(int a, int b) {
if (a > b)
return true;
return false;
}
//交换
public static void exch(int[] num, int i, int j) {
int temp = num[i];
num[i] = num[j];
num[j] = temp;
}
//排序
public static void sort(int[] num) {
for (int i = 0; i < num.length; i++) {
int min = i;
// 除开i坐标的前面的元素
for (int j = i + 1; j < num.length; j++)
// 注意理解这里两个比较对象。
// 后面的每一个元素与min坐标比较。
// 目的是找出比min坐标还小/大的值
if (less(num[j], num[min]))
min = j;
// 进行交换
exch(num, i, min);
}
}
总结
第一步,设置标记
比较出最小/最大
交换标记点下标与比较的元素。
2.插入排序
理解核心思想,取出一个元素,比较它之前的元素,进行两两交换。由于一开始就是这样操作,保证了前面的数组具有有序性,从而进行交换后一样保持有序。
代码示例
//比较
public static boolean less(int a, int b) {
if (a > b)
return true;
return false;
}
//交换
public static void exch(int[] num, int i, int j) {
int temp = num[i];
num[i] = num[j];
num[j] = temp;
}
//排序
public static void sort(int[] num) {
for (int i = 0; i < num.length; i++) {
//比较当前i,之前的元素,进行两两交换操作。(关键)
for (int j = i; j > 0 && less(num[j], num[j - 1]); j--)
exch(num, j, j - 1);
}
}
总结
比较两两元素,满足条件交换。
3.快速排序(二分法排序)
理解核心思想,选取第一位作为标记,经过一次排序后,将这个数组分为两个部分(无序的),左边的小于标记,右边的大于标记。选取第二位,重复上面操作。最终整个数组有序。
fd
public static void sort(int[] num) {
sort(num, 0, num.length - 1);
}
public static void sort(int[] num, int left, int right) {
int pos;
if (left < right) {
//算出中间位置
pos = pos(num, left, right);
//以中间位置进行分割成两部分
sort(num, left, pos - 1);
sort(num, pos + 1, right);
}
}
public static int pos(int[] num, int left, int right) {
int temp = num[left];
while (left < right) {
//右边开始寻找,与标记点比较
while (left < right && num[right] >= temp)
right--;
//发现比标记点小。将右边的小值赋值给左边,并且将左边的下标向前移位。因为下面代码要从左边搜索了。
if (left < right)
num[left++] = num[right];
//左边开始寻找,与标记点比较
while (left < right && num[left] <= temp)
left++;
//发现比标记点大,将左边的大值赋值给右边,并且将右边的下标--,因为代码要从右边搜索了。
if (left < right)
num[right--] = num[left];
}
//最终完成,最后一步是左边的值赋值给右边,所以此时的left就处于中间位置。我们将标记点值赋值给它,
num[left] = temp;
//返回分割点。
return left;
}
public static void main(String[] args) {
int[] num = new int[20];
Random random = new Random();
for (int i = 0; i < 20; i++) {
num[i] = random.nextInt(100);
}
sort(num);
for (int i :
num) {
System.out.print(i + "\t");
}
System.out.println();
}
总结
标记点
右边小的赋值给左边,左边大的赋值给右边
确定中间点,赋值标记点值,返回下标
4.希尔排序
理解核心思想,增量概念,每次在增量间比较,以及交换。缩小增量,重复比较,交换。利用的插入排序算法。
public void sort(int[] nums) {
/** 结合了插入排序 **/
/** 数字长度N **/
int N = nums.length;
/** 确认间隔长度 **/
int h = 3;
while (h < N / 3) h = 3 * h + 1;
while (h >= 1) {
/** 注意需要从i=h开始 i++ **/
for (int i = h; i < N; i++)
/** j=i开始 **/
for (int j = i; j >= h && less(nums[j], nums[j - h]); j -= h)//插入排序
exch(nums, j, j - h);
h = h / 3;
}
}
理解快速排序,改变其增量即可。
5.归并排序
理解核心思想,归并排序,类似于分支法解决问题,将一个长度很长的数组,从中间分开,分成两半,取一半,重复上述操作即可。最终变成长度为2的数组,比较后,进行交换,在末端保持了有序性。继而整体保持了有序性。
/**
* @param nums
*/
public void sort(int[] nums) {
sort(nums, 0, nums.length - 1);
}
public void sort(int[] nums, int low, int high) {
int mid = low + (high - low) / 2;
if (low < high) {
/** 左边排序 **/
sort(nums, low, mid);
/** 右边排序 **/
sort(nums, mid + 1, high);
merge(nums, low, mid, high);
}
}
private void merge(int[] nums, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int i = low;
int j = mid + 1;
int k = 0;
/** 两边合并**/
while (i <= mid && j <= high) {
if (nums[i] < nums[j]) {
temp[k++] = nums[i++];
} else {
temp[k++] = nums[j++];
}
}
/** 左边多余的合并 **/
while (i <= mid) {
temp[k++] = nums[i++];
}
/** 右边多余的合并 **/
while (j <= high) {
temp[k++] = nums[j++];
}
/** 拷贝合并后的数到原数组 **/
for (int k2 = 0; k2 < temp.length; k2++)
nums[low + k2] = temp[k2];
}
总结
实现末端长度为2的数组,进行比较交换,保持了底层有序,进而整体有序。
public static void sort(int[] n) {
for (int i = 0; i < n.length; i++) {
createMaxHeap(n, n.length - 1 - i);
exch(n, 0, n.length - 1 - i);
}
}
public static void createMaxHeap(int[] n, int lastIndex) {
int pIndex = (lastIndex - 1) / 2;
for (int i = pIndex; i >= 0; i--) {
int k = i;
while (2 * k + 1 <= lastIndex) {
int cIndex = 2 * k + 1;
if (cIndex < lastIndex)
if (n[cIndex] < n[cIndex + 1])
cIndex++;
if (n[k] < n[cIndex]) {
exch(n, cIndex, k);
k = cIndex;
} else {
//关键的,跳过,上一级父节点
break;
}
}
}
}
public static void sort(int[] n) {
int max = n[0];
int min = max;
for (int i = 0; i < n.length; i++) {
if (max < n[i])
max = n[i];
if (min > n[i])
min = n[i];
}
int[] c = new int[max - min + 1];
for (int i = 0; i < n.length; i++) {
c[n[i] - min] += 1;
}
for (int i = 0, index = 0; i < max - min + 1; i++) {
for (int j = 0; j < c[i]; j++) {
n[index++] = i + min;
}
}
}