i++; //如果节点的右孩子>左孩子,则取右孩子节点的下标
}
if(key >= arr[i]){ //根节点 >=左右子女中关键字较大者,调整结束
break;
}else{ //根节点 <左右子女中关键字较大者
arr[start] = arr[i]; //将左右子结点中较大值array[i]调整到双亲节点上
start = i; //【关键】修改k值,以便继续向下调整
}
}
arr[start] = key; //被调整的结点的值放人最终位置
}
5.快排:时间空间复杂度都是O(nlogn),不稳定。
适用于:
被排序的数据完全无序
public
static
void
quicksort(
int
[] arr,
int
low,
int
high){
if
(low < high){
int
mid =
getMiddle
(arr,low,high);
quicksort
(arr,low,mid-1);
quicksort
(arr,mid+1,high);
}
}
public
static
int
getMiddle(
int
[] arr,
int
low,
int
high){
int
key = arr[low];
while
(low < high){
while
(low < high && arr[high] >= key)
high--;
arr[low] = arr[high];
while
(low < high && arr[low] <= key)
low++;
arr[high] = arr[low];
}
arr[low] = key;
return
low;
}
6.冒泡
public
void
bubbleSort(
int
[] array){
for
(
int
i=0;i
length
;i++){
for
(
int
j=0;j
length
-1-i;j++){
if
(array[j]>array[j+1]){
int
tmp
= array[j];
Array[j] = array[j+1];
Array[j+1] = tmp;
//交换j和j+1
}
}
}
}
7.归并:时间复杂度是O(nlogn),空间复杂度
O(n)
,稳定的。
将已有序的子序列合并,得到完全有序的序列。将待排序序列R[0...n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4的有序序列;如此反复进行下去,最后得到一个长度为n的有序序列。
public
static
void
sort(
int
[] data,
int
left,
int
right) {
if
(left >= right)
return
;
// 找出中间索引
int
center = (left + right) / 2;
// 对左边数组进行递归
sort
(data, left, center);
// 对右边数组进行递归
sort
(data, center + 1, right);
// 合并
merge
(data, left, center, right);
}
public
static
void
merge(
int
[] data,
int
left,
int
center,
int
right) {
// 临时数组
int
[] tmpArr =
new
int
[data.
length
];
// 右数组第一个元素索引
int
mid = center + 1;
// third 记录临时数组的索引
int
third = left;
// 缓存左数组第一个元素的索引
int
tmp = left;
while
(left <= center && mid <= right) {
// 从两个数组中取出最小的放入临时数组
if
(data[left] <= data[mid]) {
tmpArr[third++] = data[left++];
}
else
{
tmpArr[third++] = data[mid++];
}
}
// 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
while
(mid <= right) {
tmpArr[third++] = data[mid++];
}
while
(left <= center) {
tmpArr[third++] = data[left++];
}
// 将临时数组中的内容拷贝回原数组中
// (原left-right范围的内容被复制回原数组)
while
(tmp <= right) {
data[tmp] = tmpArr[tmp++];
}
}
8.基数:
public static void sort(int[] number, int d) //d表示最大的数有多少位
{
intk = 0;
intn = 1;
intm = 1; //控制键值排序依据在哪一位
int[][]temp = newint[10][number.length]; //数组的第一维表示可能的余数0-9
int[]order = newint[10]; //数组orderp[i]用来表示该位是i的数的个数
while(m <= d)
{
for(inti = 0; i < number.length; i++)
{
intlsd = ((number[i] / n) % 10);
temp[lsd][order[lsd]] = number[i];
order[lsd]++;
}
for(inti = 0; i < 10; i++)
{
if(order[i] != 0)
for(intj = 0; j < order[i]; j++)
{
number[k] = temp[i][j];
k++;
}
order[i] = 0;
}
n *= 10;
k = 0;
m++;
}
}
9.折半查找方法适用于不经常变动而查找频繁的有序列表。