各排序方法比较

断断续续地看了《JAVA数据结构与算法》,一直没有好好整理下,久了就忘记了。这里把排序的笔记记录如下(代码都出自《JAVA数据结构与算法》):
1、 冒泡排序:
(1) 思想:从左边第一个数据项开始,跟其右边的数据项比较,如果左边的数值大于右边的,则进行交换,这样直到最后一个结束,一次循环就把最大的数放在最右边。第二次同样,到右边的倒数第二个结束,以此类推。直到所有的数据项有序。
(2) 代码:
for (int out = eItem - 1; out > 0; out--) {
for (int in = 0; in < out; in++) {
if (a[in] > a[in + 1])
swap(in, in + 1);//根据位置交换数据项
}
}

(3) 复杂度:比较和交换均为O(N2)
2、 选择排序:
(1) 思想:各数据项依次进行比较,找出最小的那个数据项,把它跟左边第一个数据项进行交换。第二次则从第二项开始,找出剩余的最小的数据项跟第二项进行交换。以此类推。
(2) 代码:
for (out = 0; out < eItem - 1; out++) {
min = out;
for (in = out + 1; in < eItem; in++)
if (a[in] < a[min])
min = in; // 取得最小的值
swap(out, min); //
}

(3) 复杂度:交换为O(N),比较仍为O(N2)
3、 插入排序:
(1) 思想:先将左边的两个数据项排好序,然后第三个数据项再跟排好序的数据项比较,插入到正确位置。之后第四个数据项再插入到已经有序的三个数据项里。以此类推。
(2) 代码:
for (out = 1; out < eItem; out++) {
long temp = a[out]; // 将当前标记对象值传给temp
in = out; // 将当前标记值的位置给IN
// 如果前一个数大于后一个数,则将前一个数的值给后一个数,同时插入位置减一
while (in > 0 && a[in - 1] > temp) {
a[in] = a[in - 1];
in--;
}
a[in] = temp;// 找到被标记的对象插入的位置
}

(3) 复杂度: O(N2),数据有序为O(N),逆序则比冒泡排序效率低
4、 希尔排序:
(1) 与插入排序类似,只是加大元素之间的间隔(插入排序为1),并在这些有间隔的元素中进行插入排序,逐步缩小间隔,直到间隔为1。
(2) 代码:
int inner, outer;
long temp;
int h = 1;
while (h <= eItem / 3)
h = h * 3 + 1;
while (h > 0) {
for (outer = h; outer < eItem; outer++) {
inner = outer;
temp = a[outer];
while (inner > h - 1 && a[inner - h] >= temp) {
a[inner] = a[inner - h];
inner -= h;
}
a[inner] = temp;
}
h = (h - 1) / 3;
}

(3) 复杂度: O(N3/2)—O(N7/6)
5、 快速排序:
(1) 取最右边的数据项值为关键字,依据此关键字将数据分为两组,小于关键字的和大于关键字的。这两组又各自进行快速排序,直到全部有序。
(2) 代码:
public void recQuickSort(int left, int right) {
if (left >= right)
return;
else {
long pivot = a[right]; // 取最右边的值为要划分的中间值关键字
int partition = partitionIt(left, right, pivot); // 关键字所在位置
recQuickSort(left, partition - 1);// 对关键字左边进行快速排序
recQuickSort(partition + 1, right);
}
}
public int partitionIt(int left, int right, long pivot) {
int leftPtr = left - 1;
int rightPtr = right;
while (true) {
while (leftPtr < right && a[++leftPtr] < pivot)
; // 找到左边区域小于关键字的位置
while (rightPtr > left && a[--rightPtr] > pivot)
;
if (leftPtr >= rightPtr)
break;
else {
swap(leftPtr, rightPtr);// 将找到的左右关键字交换
}
}
swap(leftPtr, right);
return leftPtr;
}

(3) 复杂度: O(N*logN)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值