您的位置:首页 > 理论基础

经典的几种排序方式

2017-12-02 10:40 274 查看
所谓排序就是整理文件中的记录,使之按关键字递增(或递减)次序排列起来。

稳定排序与不稳定排序:

假设 Ki = Kj ,且排序前序列中 Ri 领先于 Rj ;

若在排序后的序列中 Ri 仍领先于 Rj ,则称排序方法是稳定的。

若在排序后的序列中 Rj 仍领先于 Ri ,则称排序方法是不稳定的。

例:序列 3 15 8 8 6 9

若排序后得 3 6 8 8 9 15 稳定的#两个8 不同顺序

若排序后得 3 6 8 8 9 15 不稳定的

根据排序过程中待排序记录是否全部放置在内存中,排序分为内排和外排。

内部排序: 指的是待排序记录存放在计算机随机存储器中进行的排序过程。

外部排序: 指的是待排序记录的数量很大,以致内存一次不能容纳全部记录,在排序过程中尚需对外存进行访问的排序过程。

算法的复杂性:体现在运行该算法时的计算机所需资源的多少上,计算机资源最重要的是时间和空间(即寄存器)资源,因此复杂度分为时间和空间复杂度。

辅助空间:辅助空间是评价排序算法的一个重要指标,辅助空间是指除了存放待排序资源之外,执行算法所需要的其他存储空间。

时间复杂度:简单的说就是程序循环执行的总的次数。算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。时间复杂度常用大O符号表述,即O(f(n))。

按照排序过程中所依据的原则的不同可以分类为:

►插入排序
直接插入排序  希尔排序
►交换排序
冒泡排序  快速排序
►选择排序
简单选择排序  堆排序
►归并排序

►基数排序


介绍几种已经掌握的排序方法:

直接插入排序:

对于给定的一组记录,初始时假定第一个记录自成一个有序的序列,其余的记录为无序序列;接着从第二个记录开始,按照记录的大小依次将当前处理的记录插入到其之前的有序序列中,直至最后一个记录插入到有序序列为止。

例:将 29 18 87 56 3 27 按由小到大排序

① (29) (18 87 56 3 27)

② (18 29) (87 56 3 27)

③ (18 29 87) (56 3 27)

④ (18 29 56 87) (3 27)

⑤ ( 3 18 29 56 87) (27)

⑥ (3 18 27 29 56 87)

具体的程序看下:(由于头文件写了不好上传 请用时自行加上 下面也是)

int main()

{

int i,j,temp,length;

int a[5] = {8, 7, 3, 5, 1};

length = sizeof(a)/sizeof(a[0]);

for(i = 1; i < length; i++)

{

temp = a[i];

for(j = i-1 ;j >= 0; j–)

{

if(temp < a[j])

{

a[j+1]= a[j];

}

else

{

break;

}

}

a[j+1] = temp;

}

for(i = 0; i < length; i++)
{
printf("%d",a[i]);
}
printf("\n");
return 0;


}

稳 定 性:稳定

时间复杂度: O(n^2)

(1)初始数据正序,总比较次数:n-1

(2)初始数据逆序,总比较次数:(n2+n-1)/2= O(n2)

(3)初始数据无序,第i趟平均比较次数(i+1)/2,总次数为:(n2+3n)/4=O(n2)

(4)可见,原始数据越趋向正序,比较次数和移动次数越少。

希尔排序:

希尔排序也称为“缩小增量排序”,基本原理是:首先将待排序的元素分为多个子序列,使得每个子序的元素个数相对较少,对各个子序分别进行直接插入排序,待整个待排序序列“基本有序后”,再对所有元素进行一次直接插入排序。

希尔排序的特点:

时间复杂度:希尔排序的时间复杂性在O(nlog2n)和O(n2 )之间,大致为O(n1.3)。

稳 定 性:不稳定

具体程序如下:

int main()

{

int a[] = {2,5,7,25,89,105,34};

int length,i,j,temp,gap;

length = sizeof(a)/ sizeof(a[0]);

for(gap = length/2; gap > 0; gap /= 2)

{

for(i = gap; i < length; i++ )

{

temp = a[i];

for(j = i - gap; j >= 0 && temp < a[j];j=j-gap)

{

a[j+gap] = a[j];

}

a[j+gap]= temp;

}

}

for(i = 0; i < length; i++)

{

printf(“%d “,a[i]);

}

printf(“\n”);

return 0;

}

快速排序:

快速排序是一种非常高效的排序方法,采用“分而治之”的思想,把大的拆分为小的,小的在拆分为更小的。

原理是:对于一组给定的记录,通过一趟排序后,将原序列分为两部分,其中前部分的所有记录均比后部分的所有记录小,然后再依次对前后两部分的记录进行快速排序,递归该过程,直到序列中的所有记录均为有序为止

快速排序特点:

稳 定 性:不稳定

平均时间复杂度: O(nlog2n)

程序如下:

void Sort(int *a,int low,int high)

{

int i,j;

int index;

i = low;
j = high;
index = a[i];

if(low >= high)
{
return;
}

while(i < j)
{
while(i < j && a[j] >= index)
{
j--;
}
if(i < j)
{
a[i++] = a[j];
}
while(i < j && a[i] < index)
{
i++;
}
if(i < j)
{
a[j--] = a[i];
}
}
a[i] = index;
Sort(a,low,i - 1);
Sort(a,i + 1,high);


}

void QuickSort(int a[], int length)

{

Sort(a,0,length - 1);

}

int main()

{

int a[] = {9, 8, 15, 78, 54, 89, 21, 36};

int i;

int length = sizeof(a) /sizeof(a[0]);

QuickSort(a,length);

for(i = 0; i < length; i++)

{

printf(“%d “,a[i]);

}

printf(“\n”);

return 0;

}

归并排序:

利用递归与分治技术将数据序列划分为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列。

原理如下:对于给定的一组记录,首先将两个相邻的长度为1的子序列进行归并,得到n/2个长度为2或者1的有序子序列,在将其两两归并,反复执行此过程,直到得到一个有序的序列为止。

例:将49 38 65 97 76 13 27由小到大排序

初始化关键字:[49] [38] [65] [97] [76] [13] [27]

一趟归并后: [38 49] [65 97] [13 76] [27]

二趟归并后: [38 49 65 97] [13 27 76]

三趟归并后: [13 27 38 49 65 76 97]

归并排序特点:

平均时间复杂度: O(nlog2n)

稳 定 性: 稳定

程序如下:

void merging(int a[],int begin,int mid,int end)

{

int tmp = (int )malloc(sizeof(int)*(end - begin + 1));

int i,j,k;

i = begin;

j = mid + 1;

k = 0;

while(i <= mid && j <=end)
{
if(a[i] < a[j])
tmp[k++] = a[i++];
else
tmp[k++] = a[j++];
}

while(i <= mid)
tmp[k++] = a[i++];
while(j <= end)
tmp[k++] = a[j++];

for(i = 0;i < k;i++)
{
a[begin + i] = tmp[i];
}
free(tmp);


}

void merge_sort(int a[],int begin,int end)

{

int mid;

if(a == NULL || begin >= end)

return;

mid = (begin + end) / 2;

merge_sort(a,begin,mid);

merge_sort(a,mid + 1,end);

merging(a,begin,mid,end);

}

int main()

{

int i,length;

int a[10] = {0};

printf(“enter 10 num…\n”);

for(i = 0;i < 10;i++)

{

scanf(“%d”,&a[i]);

}

length = sizeof(a)/sizeof(int);

merge_sort(a,0,length - 1);

for(i = 0;i < length;i++)
{
printf("%d  ",a[i]);
}
return 0;


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  计算机 编程