梁老虎

人无远虑,必有近忧

导航

排序

[摘至各求职手册]

1. 插入排序

1.1 直接插入排序

直接插入排序是稳定的排序方法。(稳定与否是指关键字相同的记录在排序完成之后之间的顺序是否会交换,不交换的就是稳定的排序方法)直接插入排序的基本思想是假设待排序的记录放在数组R[1..n]中。依次将无序区的R[i...n]中记录插入到有序区R[1..i-1]中,直到最后所有记录排序完毕。这种与打扑克时整理手上的牌的类似。

实现的方法如下:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 void InsertSort(int a[], int n)
 5 {
 6     int i, j, tmp;
 7     for(i=1; i<n; i++)
 8     {
 9         tmp = a[i];
10         for(j=i-1; j>=0 && tmp<a[j]; j--)
11         {
12             a[j+1= a[j];
13         }
14         a[j+1= tmp;
15     }
16 }

 

1.2 希尔(shell)排序

希尔排序属于插入排序方法,是一种不稳定的排序方法。直接插入排序算法中,每次插入一个数,是有序序列只增加一个节点,并且对插入的下一个数没有提供任何帮组。如果比较相隔距离较远的数,使得数的移动能跨越多个元素,则进行一次比较就能消除多个元素交换。希尔(shell)排序算法先将要排序的一组数按某个增量d分成若干组,对每组中的全部元素进行排序,然后用一个小的增量对它进行再次分组,并对每个新组进行排序。当增量减小到1时,整个要排序的数被分成一组,排序完成。

实现的方法如下:

 1 #include <iostream.h>
 2 using namespace std;
 3 
 4 void ShellSort(int a[], int n)
 5 {
 6     int i, j, h, tmp;
 7     for(h=n/2; h>0; h=h/2)
 8     {
 9         for(i=h; i<n; i++)  //这个循环就是前面的直接插入排序
10         {
11             tmp = a[i];
12             for(j=i-h; (j>=0 && tmp<a[j]); j=j-h)
13             {
14                 a[j+h] = a[j];
15             }
16             a[j+h] = tmp;
17         }
18     }
19 }

 

2. 交换排序

2.1 冒泡排序

冒泡排序的思路是:将被排序的记录数组A[1..n]垂直排列,每个记录A[i]看做是重量为A[i]的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组A,凡是扫描到违反本原则的轻气泡,就使其向上漂浮。如此反复,知道最后任意两个气泡都是轻的在上,重的在下。冒泡排序是稳定的排序。

实现的方法如下:

 1void BubbleSort(int a[], int n)
 2{
 3    int i, j, tmp, exchange;
 4    for(i=0; i<n; i++)
 5    {
 6        exchange = 0//用于记录扫描时是否发生交换
 7        for(j=n-1; j>i; j--)
 8        {
 9            if(a[j] < a[j-1])
10            {
11                tmp = a[j];
12                a[j] = a[j-1];
13                a[j-1= tmp;
14                exchange = 1;
15            }

16        }

17        if(exchange!=1//说明没有发生过交换
18            return;
19    }

20}

 

 2.2 快速排序

基本思想是:将原问题分解为若干规模更小但结构与原问题相似的子问题,递归地解答这些问题,然后将这些子问题的解组合为原问题的解。在A[low..high]中任选一个记录作为基准(pivot),以此为基准将当前无序区划分为左右两个较小的子区间A[low...pivotpos-1]和A[pivotpos+1...high],并使左边子区间中所有记录的关键字均小于等于基准记录(pivot),右边的子区间中所有的记录的关键字均大于等于pivot,而基准记录位于正确的位置上,无需参加后续的排序。最后再递归解决左子区间和右子区间的排序。

实现的方法如下:

 1void QuickSort(int a[], int low, int high)
 2{
 3    int i, j, pivot;
 4    if(low < high)
 5    {
 6       pivot = a[low];
 7       i = low;
 8       j = high;
 9       while(i<j)
10       {
11           while(i<&& a[j]>=pivot)
12               j--;
13           if(i<j)
14               a[i++= a[j];
15           while(i<&& a[i]<=pivot)
16               i++;
17           if(i<j)
18               a[j--= a[i];
19       }

20       a[i] = pivot; //此时i与j是相等的,用哪个都无所谓
21        QuickSort(a, 0, i-1);
22       QuickSort(a, i+1, high); 
23    }

24}

 

3. 选择排序

3.1 直接选择排序

基本思想是:每一次从待排序的记录中选出关键字最小的记录,顺序放在已排序好的子文件的最后,直到全部记录排序完毕。

实现方法如下所示:

 1void SelectSort(int a[], int n)
 2{
 3    int i, j, tmp, l;
 4    for(i=0; i<n; i++)
 5    {
 6        tmp = a[i];
 7        l = i;
 8        for(j=i+1; j<n; j++)
 9        {
10            if(a[j]<tmp)
11            {
12                a[i] = a[j];
13                l = j;
14            }

15        }

16        if(l!=i)
17            a[l] = tmp;
18    }

19}

 

posted on 2009-10-25 21:09  梁老虎  阅读(262)  评论(0编辑  收藏  举报