排序算法

排序算法

算法导论中对排序问题的描述

输入:n个数的序列<a1,a2,...,an>。

输出:输入序列的一个重排<a'1,a'2,...a'n>,使a'1<=a'2<=...<=a'n。

(首先声明下,下面的代码中伪代码是算法导论上抄的,c代码是自己写的。所以c语言的代码如果有问题请指教。)

1.插入排序

伪代码:

复制代码
1 INSERSION-SORT(A)
2 for j <- 2 to length[A]
3     do key <- A[j]
4        i <- j-1
5     while i>0 and A[i]>key
6         do A[i+1] <- A[i]
7            i <- i-1
8     A[i+1] <- key
复制代码

c实现

复制代码
 1 void InsertionSort(int A[],int n)
 2 {
 3     int key;
 4     int i,j;
 5     for(i=1;i<n;i++)
 6     {
 7         key = A[i];
 8         j = i-1;
 9         while(key >= A[j] && j>=0)
10         {
11             A[j+1] = A[j];
12             j--;
13         }
14         A[j+1] = key;
15     }
16 }
复制代码
  • 2.冒泡排序

伪代码:

BUBBLESORT(A)
for i <- 1 to length[A]
    do for j <- length[A] downto i+1
           do if A[j]<A[j-1]
              then exchange A[j] <-> A[j-1]

c实现:

复制代码
 1 void BubbleSort(int A[],int n)
 2 {
 3     int i,j;
 4     int tmp;
 5     for(i=0;i<n;i++)
 6     {
 7         for(j = n-1;j>=i+1;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             }
15         }
16     }
17 }
复制代码

在冒泡排序中如果做一个判断,在一趟起泡的过程中如果没有任何一次交换就终止循环。这样可以节省一些时间的开销。

  • 3.归并排序
复制代码
 1 MERGE(A,p,q,r)
 2 n1 <- q-p+1
 3 n2 <- r-q
 4 creat arrays L[1...n1+1]andR[1...n2+1]
 5 for i <- 1 to n1
 6     do L[i] <- A[p+i-1]
 7 for j <- 1 to n2
 8     do R[j] <- A[p+j]
 9 L[n1+1] <-10 R[n2+1] <-11 i <- 1
12 j <- 1
13 for k <- p to r
14     do if L[i]<=R[j]
15           then A[k] <- L[i]
16                i <- i+1
17           else A[k] <- R[j]
18                j <- j+1
19                
20 MERGE-SORT(A,p,r)
21 if p<r
22    then q <- └(p+q)/223         MERGE-SORT(A,p,q)
24         MERGE-SORT(A,q+1,r)
25         MERGE(A,p,q,r)
复制代码

c实现:

复制代码
 1 void Merge(int A[],int p,int q,int r)
 2 {
 3     int n1,n2;
 4     n1 = q-p+1;
 5     n2 = r-q;
 6     int *L = (int *)malloc(sizeof(int)*(n1+1));
 7     int *R = (int *)malloc(sizeof(int)*(n2+1));
 8     int i,j;
 9     for(i=0;i<n1;i++)
10     {
11         L[i] = A[p+i];
12     }
13     for(j=0;j<n2;j++)
14     {
15         R[j] = A[q+j+1];
16     }
17     L[n1] = INT_MAX;
18     R[n2] = INT_MAX;
19     i = 0;
20     j = 0;
21     int k;
22     for(k=p;k<=r;k++)
23     {
24         if(L[i]<=R[j])
25         {
26             A[k] = L[i];
27             i++;
28         }
29         else
30         {
31             A[k] = R[j];
32             j++;
33         }
34     }
35     free(L);
36     free(R);
37 }
38 void MergeSort(int A[],int p,int r)
39 {
40     int q;
41     if(p<r)
42     {
43         q = p + (r-p)/2;
44         MergeSort(A,p,q);
45         MergeSort(A,q+1,r);
46         Merge(A,p,q,r);
47     }
48 }
复制代码
  • 4.堆排序

伪代码:

复制代码
 1 PARENT(i)
 2   return i*2
 3 LEFT(i)
 4   return 2i
 5 RIGHT(i)
 6   return 2*i+1
 7 MAX-HEAPIFY(A,i)
 8 l <- LEFT(i)
 9 r <- RIGHT(i)
10 if l<=heap-size[A] and A[l]>A[i]
11    then largest <- l;
12    else largest <- i;
13 if r<=heap-size(A) and A[r]>A[largest]
14    then largest <- r
15 if largest != i
16    then exchange A[i] <-> A[largest]
17         MAX-HEAPIFY(A,largest)
18 BUILD-MAX-HEAP(A)
19 heap-size[A] = length[A]
20 for i <- └length[A]/2downto 1
21     do MAX-HEAPIFY(A,i)
22 HEAP-SORT(A)
23 BUILD-MAX-HEAP(A)
24 for i <-length[A] downto 2
25     do exchange A[1] <-> A[i]
26        heap-size[A] <- heap-size[A]-1
27        MAX-HEAPIFY(A,1)
复制代码

c实现:

复制代码
 1 #define PARENT(i)(((i)-1)/2)
 2 #define LEFT(i)(2*((i)+1)-1)
 3 #define RIGHT(i)(2*((i)+1))
 4 void MaxHeapify(int A[],int i,int size)
 5 {
 6     int l = LEFT(i);
 7     int r = RIGHT(i);
 8     int largest = i;
 9     int tmp;
10     if(l<size && A[i]<A[l])
11     {
12         largest = l;
13     }
14     if(r<size && A[r]>A[largest])
15     {
16         largest = r;
17     }
18     if(largest != i)
19     {
20         tmp = A[i];
21         A[i] = A[largest];
22         A[largest] = tmp;
23         MaxHeapify(A,largest,size);
24     }
25 }
26 void BuildMaxHeap(int A[],int size)
27 {
28     int i;
29     for(i=size/2;i>=0;i--)
30     {
31         MaxHeapify(A,i,size);
32     }
33 }
34 void HeapSort(int A[],int size)
35 {
36     BuildMaxHeap(A,size);
37     int i;
38     int j;
39     int tmp;
40     for(i=size-1;i>0;i--)
41     {
42         tmp = A[i];
43         A[i] = A[0];
44         A[0] = tmp;
45         MaxHeapify(A,0,i);
46     }
47 }
复制代码
  • 5.基数加桶排序(用了两个桶,分别装0,1)

基数排序伪代码:

1 RADIX-SORT(A,D)
2 for i <- 1 to d
3     do use a stable sort to sort array A on digit i

桶排序伪代码:

复制代码
1 BUCKET-SORT(A)
2 n <- length[A]
3 for i <- 1 to n
4     do insert A[i] into list B[└nA[i]┘]
5 for i <- 0 to n-1
6     do sort list B[i] with insertion sort
7 concatenate the lists B[0],B[1],...,B[n-1] together in order
复制代码

c实现

复制代码
 1 #define GET(X,N)(((X>>(N-1))&0x1))/*获取第n bit*/
 2 void RadixBucketSort(int A[],int n)
 3 {
 4     int * Bucket = malloc(sizeof(int)*n);/*一个数组当两个桶用的*/
 5     int i,j,z,num,pos1,pos2;
 6     for(num=1;num<32;num++)
 7     {
 8         i =0;
 9         j=n-1;
10         for(z=0;z<n;z++)
11         {
12             if(GET(A[z],num)==1)
13             {
14                 Bucket[i]=A[z];
15                 i++;
16             }
17             else
18             {
19                 Bucket[j]=A[z];
20                 j--;
21             }
22         }
23         pos1 = 0;
24         pos2 = n-1;
25         for(z=0;z<n;z++)
26         {
27             if( pos1!=i )
28             {
29                 A[z]=Bucket[pos1];
30                 pos1++;
31             }
32             else
33             {
34                 A[z]=Bucket[pos2];
35                 pos2--;
36             }
37         }
38 
39     }
40     free(Bucket);
41 }
复制代码

上面的算法中,算是基数排序加桶排序吧。我把一个数字从低到高每一个二进制位作为基数排序中的每一趟。也就是说我把一个int类型分成31个位。而每个二进制位只有1或0两种可能。所以将数据放入两个桶中时就自然的排好了序。所以我认为自己用了桶排序,呵呵。因为以上的原因,所以算法中只能对正数进行处理。如果要对负数或其他类型的数据进行排序的话,就要重新改进算法了。所以这些算法是有适用范围的。但比起比较排序,这些排序算法确实要快些。在数量很大的时候经过测试确实上面的算法比快排要快,呵呵。

 
 
分类: algorithm
原文地址:https://www.cnblogs.com/Leo_wl/p/2868128.html