选择排序、堆排序

Posted on 2018-12-28 16:34  金色的省略号  阅读(161)  评论(0编辑  收藏  举报

  一、选择排序法(selection sort)的基本思想是,第i趟选择排序通过n-i次关键码的比较,从n-i+1个记录中选出关键码最小的记录,并和第i个记录进行交换。选择排序是不稳定的,优于冒泡排序

 1 #include <stdio.h>
 2 #include <string.h>
 3 /* 
 4 中国
 5 韩国
 6 澳大利亚
 7 朝鲜
 8 日本
 9  */
10 int main()
11 {
12     char tmp[100], str[5][100];
13     int i, j;
14     for (i = 0; i < 5; i++)
15         gets(str[i]); /* 输入五个国家名称     */
16     printf("\n");
17 
18     for (i = 0; i<5 - 1; ++i)
19     {
20         strcpy(tmp, str[i]); /* tmp初始值为第i元素 */
21         int t = i;
22         for (j = i + 1; j<5; ++j)
23         {
24             if (strcmp(tmp, str[j]) > 0)
25             { 
26                 strcpy(tmp, str[j]);/* tmp第i元素后最小的元素 */
27                 t = j;
28             }
29         }
30         if (t != i)/* 第i元素不是有序的交换 */
31         { 
32             strcpy(str[t],str[i]);/* 第i元素放到其后最小的元素位置 */
33             strcpy(str[i],tmp);   /* 第i元素后最小的元素, 放到第i元素位置, 有序 */
34         }
35     }
36 
37     for (i = 0; i < 5; i++)/* 排序后输出 */
38         puts(str[i]);
39     return 0;
40 }

 

/*选择排序--递归*/
void SelectionSort(char a[][100], int left, int right)
{
    if(left<right){
        int j; 
        char t[100];
        for(j=right; left<j; j--){
            if(strcmp(a[j],a[left])<0)/*与最左边的比较*/ 
            {
                strcpy(t,a[left]);strcpy(a[left],a[j]);strcpy(a[j],t);
            }      
        }
        SelectionSort(a,j+1,right);/*递归*/
    }
}

 

/*选择排序--递归*/
void SelectionSort(int *a,int left, int right)
{
    if(left<right){
        int j,t; 
        for(j=right; left<j; j--){
            if(a[j]<a[left])/*与最左边的比较*/ 
                t=a[left],a[left]=a[j],a[j]=t;  
        }
        SelectionSort(a,j+1,right);/*递归*/
    }
}

 

 1 #include <iostream>
 2 #include <array>
 3 
 4 template <typename T,int N>
 5 void Sort(std::array<T,N> &list){
 6     constexpr int size = N;
 7     for(int i = 0; i<size-1; ++i){
 8         T min = list[i];
 9         int index = i;
10         for(int j = i+1; j<size; ++j){
11             if(min>list[j]){
12                 min = list[j];
13                 index = j;
14             }                
15         }
16         if(index != i){
17             list[index] = list[i];
18             list[i] = min;
19         }
20     }    
21 }
22 
23 int main() 
24 {
25     std::array x{5,6,8,9,1,2,3,7};        
26     
27     Sort<int,8>(x);
28 
29     for(auto i: x){
30       std::cout<<i<<"  ";
31     }
32     return 0;
33 }

  二、堆排序,不如希尔排序,堆排序是不稳定

typedef int ElementType;
void Swap( ElementType *a, ElementType *b )
{
     ElementType t = *a; *a = *b; *b = t;
}
  
void PercDown( ElementType A[], int p, int N )
{ /* 改编代码4.24的PercDown( MaxHeap H, int p )    */
  /* 将N个元素的数组中以A[p]为根的子堆调整为最大堆 */
    int Parent, Child;
    ElementType X;
 
    X = A[p]; /* 取出根结点存放的值 */
    for( Parent=p; (Parent*2+1)<N; Parent=Child ) {
        Child = Parent * 2 + 1;
     /*Child!=N-1  是否有右子结点 */
        if( (Child!=N-1) && (A[Child]<A[Child+1]) )
            Child++;  /*左右子结点的最大值*/
        if( X >= A[Child] ) break; /* 找到了合适位置 */
        else  /* 下滤X */
            A[Parent] = A[Child];
    }
    A[Parent] = X;
}
 
void HeapSort( ElementType A[], int N ) 
{ /* 堆排序 */
     int i;
       
     for ( i=N/2-1; i>=0; i-- )/* 建立最大堆 */
         PercDown( A, i, N );
      
     for ( i=N-1; i>0; i-- ) {
         /* 删除最大堆顶 */
         Swap( &A[0], &A[i] ); 
         PercDown( A, 0, i );
     }
}