排序总结
排序的稳定性
假设ki=kj(1≤i≤n,1≤j≤n,i≠j),且在排序前的序列中ri领先于rj(即i<j)。如果排序后ri仍领先于rj,则称所用的排序方法是稳定的;反之,若可能使得排序后的序列中rj领先ri,则称所用的排序方法是不稳定的。
影响排序算法的因素
时间性能。排序是数据处理中经常执行的一种操作,往往属于系统的核心部分,因此排序算法的时间开销是衡量其好坏的最重要的标志。在内排序中,主要进行两种操作:比较和移动。比较指关键字之间的比较,这是要做排序最起码的操作。移动指记录从一个位置移动到另一个位置,事实上,移动可以通过改为记录的存储方式来予以避免。总之,高效率的内排序算法应该是具有尽可能少的关键字比较次数和尽可能少的记录移动次数。
辅助空间。评价排序算法的另一个主要标准是执行算法所需要的辅助存储空间。辅助存储空间是除了存放待排序所占用的存储空间之外,执行算法所需要的其他存储空间。
算法的复杂性。注意这里指的是算法本身的复杂度,而不是指算法的时间复杂度。显然算法过于复杂也会影响排序的性能。
基本的排序种类
交换排序:包括冒泡排序、快速排序
选择排序:包括选择排序、堆排序
插入排序:包括直接插入排序、希尔(shell)排序
合并排序:归并排序
几种基本的排序比较
实验数据比较
随机50w个数据结果比较 随机5w个数据结果比较
源代码(java):
public class Sort_Comparsion {
public static void main(String[] args) {
Sort_Comparsion sc = new Sort_Comparsion();
sc.bubblesort();
sc.selectsort();
sc.insertionsort();
sc.shellsort();
sc.heapsort();
sc.quicksort();
sc.mergesort();
}
// 冒泡排序
public void bubblesort() {
int[] list = new int[50000];
for (int i = 0; i < list.length; i++) {
list[i] = (int) (Math.random() * 1000);
}
long start = System.currentTimeMillis();
for (int i = 0; i < list.length; i++) {
for (int j = i; j < list.length; j++) {
if (list[i] > list[j]) {
int temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
long end = System.currentTimeMillis();
System.out.println("冒泡排序耗时:" + (end - start));
}
// 选择排序
public void selectsort() {
int[] list = new int[50000];
for (int i = 0; i < list.length; i++) {
list[i] = (int) (Math.random() * 1000);
}
long start = System.currentTimeMillis();
for (int i = 0; i < list.length; i++) {
int min = i, temp = 0;
for (int j = i; j < list.length; j++)
if (list[j] < list[min])
min = j;
temp = list[i];
list[i] = list[min];
list[min] = temp;
}
long end = System.currentTimeMillis();
System.out.println("选择排序耗时:" + (end - start));
}
// 插入排序
public void insertionsort() {
int[] list = new int[50000];
for (int i = 0; i < list.length; i++) {
list[i] = (int) (Math.random() * 1000);
}
long start = System.currentTimeMillis();
for (int j = 1; j < list.length; j++) {
int k = j, temp = list[j];
while (k > 0 && list[k - 1] > temp) {
list[k] = list[k - 1];
k--;
}
list[k] = temp;
}
long end = System.currentTimeMillis();
System.out.println("直接插入排序耗时:" + (end - start));
}
// 希尔排序
public void shellsort() {
int[] list = new int[50000];
for (int i = 0; i < list.length; i++) {
list[i] = (int) (Math.random() * 1000);
}
long start = System.currentTimeMillis();
int step = list.length;
while (step > 1) {
step = step / 2;
for (int i = 0; i < step; i++)// 用来作用与小组内的 增加
{
for (int j = step; j < (list.length / step) * step; j += step) {
int k = i + j, temp = list[j + i];
while (k > i && list[k - step] > temp) {
list[k] = list[k - step];
k = k - step;
}
list[k] = temp;
}
}
}
long end = System.currentTimeMillis();
System.out.println("希尔排序耗时:" + (end - start));
}
// 堆排序
public void heapsort() {
int[] list = new int[50001];
for (int i = 1; i < list.length; i++) {
list[i] = (int) (Math.random() * 1000);
}
long start = System.currentTimeMillis();
for (int i = (list.length - 1) / 2; i > 0; i--) {
hs(list, i, list.length - 1);
}
for (int j = list.length - 1; j > 0; j--) {
int temp = list[j];
list[j] = list[1];
list[1] = temp;
hs(list, 1, j - 1);
}
long end = System.currentTimeMillis();
System.out.println("堆排序耗时:" + (end - start));
}
public void hs(int[] list, int parent, int max) {
int temp = list[parent];
for (int j = 2 * parent; j <= max; j *= 2) {
if (j < max && list[j] < list[j + 1])
j++;
if (list[j] > temp) {
list[parent] = list[j];
parent = j;
} else
break;
}
list[parent] = temp;
}
// 快速排序
public void quicksort() {
int[] list = new int[50000];
for (int i = 0; i < list.length; i++) {
list[i] = (int) (Math.random() * 1000);
}
long start = System.currentTimeMillis();
qs(list, 0, list.length - 1);
long end = System.currentTimeMillis();
System.out.println("快速排序耗时:" + (end - start));
}
public void qs(int[] list, int head, int tail) {
if (head < tail) {
int mid = qss(list, head, tail);
qs(list, head, mid - 1);
qs(list, mid + 1, tail);
}
}
public int qss(int[] list, int top, int down) {
int temp = list[top];
while (top != down) {
while (top < down && list[down] > temp)
down--;
list[top] = list[down];
while (top < down && list[top] <= temp)
top++;
list[down] = list[top];
}
list[top] = temp;
return top;
}
// 归并排序
public void mergesort() {
int[] list = new int[50000];
for (int i = 0; i < list.length; i++) {
list[i] = (int) (Math.random() * 1000);
}
long start = System.currentTimeMillis();
int[] temp = new int[list.length];
ms(list, temp, 0, list.length - 1);
long end = System.currentTimeMillis();
System.out.println("归并排序耗时:" + (end - start));
}
public void ms(int[] list, int[] temp, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
ms(list, temp, left, mid);
ms(list, temp, mid + 1, right);
mss(list, temp, left, mid + 1, right);
}
}
public void mss(int[] list, int[] temp, int leftbegin, int rightbegin,
int rightend) {
int leftend = rightbegin - 1;
int len = rightend - leftbegin + 1;
int temparray = leftbegin;
while (rightbegin <= rightend && leftbegin <= leftend) {
if (list[leftbegin] < list[rightbegin])
temp[temparray++] = list[leftbegin++];
else
temp[temparray++] = list[rightbegin++];
}
while (leftbegin <= leftend)
temp[temparray++] = list[leftbegin++];
while (rightbegin <= rightend)
temp[temparray++] = list[rightbegin++];
for (int i = 0; i < len; i++, rightend--)
list[rightend] = temp[rightend];
}
}