八大排序之交换排序

冒泡排序:顾名思义,即每趟排序通过对相邻两个元素比较,越大的元素会因交换“浮”到数组的顶端处。
算法思想:对于一组数据,依次将两个相邻元素比较,若前者大于后者元素,则将两者位置交换,直到最后的待排序元素位置。重复进行上述操作,最后数组完全有序。
排序过程如图所示:
八大排序之交换排序

具体代码如下:
  C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#incude

void  BubbleSort( int  arr[],  int  len)
{
    
for ( int   0 len  1 i++)
    {
        
bool  flag  false  //设置标志
        
for ( int   0 len  1 j++)
        {
            
if (arr[j] arr[j  1 ])
            {
                
int  tmp arr[j  1 ];
                arr[j 
1 arr[j];
                arr[j] tmp;
                flag 
true ;
            }
        }

        
if (!flag == true) //如果条件为真,表明待排序数列已有序,直接跳出循环!
        {
            
break ;
        }
    }
}

int  main()
{
    
int  a[] { 3 2 1 4 8 7 6 5 10 9 };
    
int  len  sizeof (a)  sizeof (a[ 0 ]);
    BubbleSort(a, len);
    
for ( int   0 len; i++)
    {
        printf(
"%d  " a[i]);
    }
}
注:此段代码实现了冒泡排序算法并进行了优化,我们设置一个flag标志,当内循环不执行了,即falg等于false时,break跳出外层循环,使排序躺数可能减少。

快速排序:通过一趟排序将一组数据分成两个独立的部分,一部分数据比另一部分都小,然后用这个操作将两个部分分别进行排序,整个排序过程可以递归进行,最后全部元素成为有序序列。
排序过程如图所示:
八大排序之交换排序

递归实现代码如下:
  C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include
#include
#include
void  Swap( int  arr[],  int  a1,  int  a2)
{
    
int  tmp arr[a1];
    arr[a1] arr[a2];
    arr[a2] tmp;
}

void  Gather( int  arr[],  int  low,  int  high,  int  pos,  int  *left,  int  *right)
{
    
if (low high)
    {
        
int  count pos- 1 ;
        
for ( int  pos- 1 >= low; i--)
        {
            
if (arr[i] == arr[pos])
            {
                Swap(arr, i, count);
                count--;
            }
        }
        *left count;
        
int  num pos+ 1 ;
        
for ( int  pos+ 1 <= high; j++)
        {
            
if (arr[j] == arr[pos])
            {
                Swap(arr, j, num);
                num++;
            }
        }
        *right num;
    }
}
int  Partion( int  arr[],  int  low,  int  high)  //具体分成一部分比另一部分大的排序
{
    
int  tmp arr[low];
    
while (low high)
    {
        
while (low<=arr[high]) high--;
        arr[low] arr[high];
        
while (low=arr[low]) low++;
        arr[high] arr[low];
    }
    arr[low] tmp;
    
return  low;
}

void  TakeSecondMaxnum( int  arr[],  int  low,  int  mid,  int  high) //三分取中法
{
    
if (arr[mid] arr[high])
    {
        Swap(arr, mid, high);
    }
    
if (arr[low] arr[high])
    {
        Swap(arr, low, high);
    }
    
if (arr[low] arr[mid])
    {
        Swap(arr, low, mid);
    }
}

void  InsertSort( int  arr[],  int   low,  int  high) //优化一数据量小时,不适宜使用快排,而用插入排序更好
{
    
int  i, j;
    
for  (i  2 high-low+ 1 ++i)
    {
        arr[
0 arr[i];
        
for  (j  1 arr[j] arr[ 0 ]; --j)
        {
            arr[j 
1 arr[j];
          
        arr[j 
1 arr[ 0 ];
    }
}
void  Sort( int  arr[],  int  low,  int  high)
{
            
if (low high)
            {
                Swap(arr, low, rand()%(high-low)+low); 
// 优化二,在最坏情况全部有序时交换基准点
            TakeSecondMaxnum(arr, low, (high-low)/ 2 +low, high); //优化三,基准点选取“中数”
             int  pos Partion(arr, low, high);
            
int  left pos- 1 ;
            
int  right pos+ 1 ;
            Gather(arr, low, high, pos, &left, &right);
//优化四,聚集与基准点相同的元素,这些元素不参加之后排序
            Sort(arr, low, left);
            Sort(arr, right, high); 
           
}
void  QuickSort( int  arr[],  int  len)
{
    Sort(arr, 
0 len- 1 );
}

int  main()
{
    
int  a[] { 2 , 3 , 1 , 6 , 5 , 4 , 9 , 8 , 7 , 0 , 21 , 34 , 32 , 27 , 87 , 56 , 43 , 48 , 76 , 29 , 55 };
    
int  len  sizeof (a)/ sizeof (a[ 0 ]);
    QuickSort(a, len);
    
    
for ( int   0 len; i++)
    {
        printf(
"%d " ,a[i]);
    }
    printf(
"\n" );
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值