一,九大排序的种类及其算法复杂度:
二,九大排序的具体思路及其实现代码:
1,冒泡排序:
基本的思路:
在排序过程中总是小数往前放,大数往后放,相当于气泡往上升。
稳定性:
排序过程中只交换相邻两个元素的位置。因此,当两个数相等时,是没必要交换两个数的位置的。所以,它们的相对位置并没有改变,冒泡排序算法是稳定的!
代码的实现:
void BubbleSort(int array[],int n)
{
int i=0;
int j=0;
int temp=0;
int flag = 0;
for(i=0;i<n - 1 ;i++) /*外循环控制排序的总趟数*/
{
flag = 0; /*本趟排序开始前,交换标志应为假*/
for(j=n-1;j > i;j--) /*内循环控制一趟排序的进行*/
{
if(array[j] < array[j-1] ) /*相邻元素进行比较,若逆序就交换*/
{
temp =array[j];
array[j] = array[j-1];
array[j-1] = temp;
flag = 1; /*发生了交换,故将交换标志置为真*/
}
}
if (flag == 0) /*本趟排序未发生交换,提前终止算法*/
break;
2,选择排序
基本思路:
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面)。
代码实现:
- void select_sort(int a[],int n)//n为数组a的元素个数
- {
- //进行N-1轮选择
- for(int i=0; i<n-1; i++)
- {
- int min_index = i;
- //找出第i小的数所在的位置
- for(int j=i+1; j<n; j++)
- {
- if(a[j] < a[min_index])
- {
- min_index = j;
- }
- }
- //将第i小的数,放在第i个位置;如果刚好,就不用交换
- if( i != min_index)
- {
- int temp = a[i];
- a[i] = a[min_index];
- a[min_index] = temp;
- }
- }
- }
3,快速排序
基本思路:
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动
代码实现:
void
sort(
int
*a,
int
left,
int
right)
{
if
(left >= right)
/*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/
{
return
;
}
int
i = left;
int
j = right;
int
key = a[left];
while
(i < j)
/*控制在当组内寻找一遍*/
{
while
(i < j && key <= a[j])
/*而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升
序还是降序)2,没有符合条件1的,并且i与j的大小没有反转*/
{
j--;
/*向前寻找*/
}
a[i] = a[j];
/*找到一个这样的数后就把它赋给前面的被拿走的i的值(如果第一次循环且key是
a[left],那么就是给key)*/
while
(i < j && key >= a[i])
/*这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,
因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/
{
i++;
}
a[j] = a[i];
}
a[i] = key;
/*当在当组内找完一遍以后就把中间数key回归*/
sort(a, left, i - 1);
/*最后用同样的方式对分出来的左边的小组进行同上的做法*/
sort(a, i + 1, right);
/*用同样的方式对分出来的右边的小组进行同上的做法*/
/*当然最后可能会出现很多分左右,直到每一组的i = j 为止*/
}
4,直接插入排序:
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法
基本思路:
每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
代码实现:
void insert_sort(int a[],int n){
int i,j,temp;
for(i=1;i<n;i++)//需要选择n-1次;
{
temp=a[i];
//暂存下标为1的数,下标从1开始,因为下标开始为0的数,前面没有任何数,此时认为他是排好顺序的
for(j=i-1;j>=0&&temp<a[j];j--){
a[j+1]=a[j];//如果满足条件就往后挪,最坏的情况是temp比a[0]小,他要放在最前面
}
a[j+1]=temp;//找到下标为i的数的放置位置
}
}
void print_arry(int a[],int len)
{
for(int i=0;i<len;i++)
{
cout<<a[i]<<' ';
}
cout<<endl;
}
5,希尔排序:
基本思路:
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量



代码实现:
#include<stdio.h> #include <stdio.h> void shellsort(int *a, int n) { int i, j, k, t; k = n / 2; while(k > 0) { for(i = k; i < n; i++){ t = a[i]; j = i - k; while(j >= 0 && t < a[j]) { a[j + k] = a[j]; j = j - k; } a[j + k] = t; } k /= 2; } } int main() { int a[] = {8,10,3,5,7,4,6,1,9,2}; int N; N = sizeof(a) / sizeof(a[0]); shellsort(a, N); for(int k = 0; k < N; k++) printf("a[%d] = %d\n",k,a[k]); return 0; }