排序算法(冒泡排序,选择排序,插入排序,快速排序) 数组的排序算法

 

数组的排序算法

选择排序

每次选择所要排序得数组中的最大值(由大到小排序,由小到大排序则选择最小值)的数组元素,将这个数组元组的值与最前面没有排序的数组元素进行交换,

第一次排序之后,最大的数字来到了第一位,再从第二个元素开始找,找到最大的元素,与第二个交换位置

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
#include <stdio.h>
 
int  main( int  argc,  char  *argv[])
{
     int  i,j;
     int  a[10];
     int  temp;
     int  index;
     printf( "为数组元素赋值\n" );
     for (i=0;i<10;i++){
         printf( "a[%d]=" ,i);
         scanf( "%d" ,&a[i]);
     }
     for (i=0;i<9;i++){ //外层循环0~8这9个元素
         temp=a[i];  //假设最大值
         index=i;  // 记录假设最大值索引
         for (j=i+1;j<10;j++){ // 内层循环,排序后的元素
             if (a[j]>temp){ //取最大值
                 temp=a[j];  //重置最大值
                 index=j;  //重置最大值索引
             }
         }
         // 交换元素位置
         a[index]=a[i];
         a[i]=temp;
     }
     
     // 输出数组
     for (i=0;i<10;i++){
         printf( "%d\t" ,a[i]);
         if (i==4){  //输出换行
         
         printf( "\n" );
         }
         }
 
     return  0;
}

python做选择排序

1
2
3
4
5
6
7
8
9
# 扫描无序区,从无序区中找出一个极端值,放入有序区
def  select_sort(li):  # 选择
     for  in  range ( len (li) - 1 ):  # i表示第几次,有多少元素我就要扫几-1次
         # 找无序区最小值,保存最小值的位置
         min_pos  =  i      # 假设起始值最小,min_pos保存最小值的索引
         for  in  range (i + 1 len (li)):  # 第i趟开始时 无序区:li[i:],自己不与自己比较,所以i+1
             if  li[j] < li[min_pos]:  # 满足条件,我存的值比后面的值大,则把后面的值的所以设置为最小值索引
                 min_pos  =  j
         li[min_pos], li[i]  =  li[i], li[min_pos]  # 交换两个值的位置

冒泡排序

每次比较相邻的两个数,将最小的数(从小到大排序)排在较大的数前面.

经过一次排序之后最小的数到达了最前面的位置,并将其他的数字依次向后移动,第二次排序时,将从第二个数开始最小的数移动到第二的位置,依次类推

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
#include <stdio.h>
  
int  main( int  argc,  char  *argv[])
{
     int  i,j;
     int  a[10];
     int  temp;
     printf( "为数组元素赋值\n" );
     for (i=0;i<10;i++){
         printf( "a[%d]=" ,i);
         scanf( "%d" ,&a[i]);
     }
     for (i=1;i<10;i++){ //外层循环1~9这9个元素
         for (j=9;j>=i;j--){ //从后向前循环i后面的元素
         if (a[j]<a[j-1]){ //前面的数大于后面的数,交换
             temp=a[j-1];
             a[j-1]=a[j];
             a[j]=temp;
             }
         }
     }
     
     // 输出数组
     for (i=0;i<10;i++){
         printf( "%d\t" ,a[i]);
         if (i==4){  //输出换行
         
         printf( "\n" );
             }
         }
     return  0;
}

python做冒泡排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 冒泡排序,一遍遍扫描未归位区,比较相邻的两个数字,满足条件则交换,每次使一个元素归位
 
def  bubble_sort(li):  # 冒泡
     for  in  range ( len (li) - 1 ):  # i表示第几次,有多少元素我就要扫几-1次
         for  in  range ( len (li) - i - 1 ):  # 比较元素的位置,len(li)-1-i是未归位区的最大索引
             if  li[j] > li[j + 1 ]:  # 满足条件 将两个数值交换,这里是前面比后面大
                 li[j], li[j + 1 =  li[j + 1 ], li[j]
 
 
def  bubble_sort_1(li):  # 优化冒泡
     for  in  range ( len (li) - 1 ):  # i表示第几次,有多少元素我就要扫几次
         exchange  =  False  # 增加了一个标志位,如果依次循环中没有发生交换,则顺序已经是有序的了,可以直接退出
         for  in  range ( len (li) - i - 1 ):  # 比较元素的位置,len(li)-1-i是未归位区的最大索引
             if  li[j] > li[j + 1 ]:
                 li[j], li[j + 1 =  li[j + 1 ], li[j]
                 exchange  =  True
         if  not  exchange:
             return

插入排序

插入排序就像是摸扑克,第一张算是有序区,从后面的无序区拿扑克向有序区中插

python

1
2
3
4
5
6
7
8
9
10
def  insert_sort(li):   # 插入
     for  in  range ( 1 len (li)):  # i是摸到的牌的下标,第一个属于有序区,所以从第二个开始
         tmp  =  li[i]  # 手里牌的大小
         =  -  1  # j是手里最后一张牌的下标
         # 如果tmp大于我手里第j个元素,他就应该放在第j个位置上,如果小于就继续向前比较
         while  j > =  0  and  li[j] > tmp:    # 两个终止条件:j小于0表示tmp是最小的 顺序不要乱
             # 因为保存了i索引位置的值,所以大于tmp的数都向后移动一位,j自减
             li[j + 1 =  li[j]
             - =  1
         li[j + 1 =  tmp

快速排序

快排采用的递归的思路
是以一个数字为基准(第0个元素),将列表分为大于他的和小于他的两部分,递归进行直至列表少于一个元素

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
def  partition(li, left, right):  # 归位
     # randi = random.randint(left, right)
     # li[randi], li[left] = li[left], li[randi]
     '''
     将一个列表分成左右两部分
     :param li: 列表
     :param left: 开始索引
     :param right: 结束索引
     :return: 返回中间索引
     '''
     tmp  =  li[left]  # 取最左边的值,作为中间值
     while  left < right:  # 左索引一定要小于右索引,
         while  left < right  and  li[right] > =  tmp:
             # 从后向前找一个小于tmp的元素,找不到就将索引-1向前找
             # = tmp可以使right的值是tmp左边的索引
             right  - =  1
         li[left]  =  li[right]  # 找到之后放到最左边 ,此时right位置的值有两个,
         while  left < right  and  li[left] < =  tmp:
             # 在从前往后找一个比tmp大的,找不到就将索引+1向后找
             # = tmp可以使right的值是tmp右边的索引
             left  + =  1
         li[right]  =  li[left]  # 找到之后放到right位置,
     # 当左右索引位置重合时循环结束
     li[left]  =  tmp
     return  left
 
 
def  _quick_sort(li, left, right):  # 递归
     if  left < right:     # 至少两个元素
         mid  =  partition(li, left, right)  # 取中间索引,将两面进行递归
         _quick_sort(li, left, mid  -  1 )
         _quick_sort(li, mid  +  1 , right)

归位图解

扫描二维码关注公众号,回复: 80955 查看本文章

 

 
分类:  算法

数组的排序算法

选择排序

每次选择所要排序得数组中的最大值(由大到小排序,由小到大排序则选择最小值)的数组元素,将这个数组元组的值与最前面没有排序的数组元素进行交换,

第一次排序之后,最大的数字来到了第一位,再从第二个元素开始找,找到最大的元素,与第二个交换位置

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
#include <stdio.h>
 
int  main( int  argc,  char  *argv[])
{
     int  i,j;
     int  a[10];
     int  temp;
     int  index;
     printf( "为数组元素赋值\n" );
     for (i=0;i<10;i++){
         printf( "a[%d]=" ,i);
         scanf( "%d" ,&a[i]);
     }
     for (i=0;i<9;i++){ //外层循环0~8这9个元素
         temp=a[i];  //假设最大值
         index=i;  // 记录假设最大值索引
         for (j=i+1;j<10;j++){ // 内层循环,排序后的元素
             if (a[j]>temp){ //取最大值
                 temp=a[j];  //重置最大值
                 index=j;  //重置最大值索引
             }
         }
         // 交换元素位置
         a[index]=a[i];
         a[i]=temp;
     }
     
     // 输出数组
     for (i=0;i<10;i++){
         printf( "%d\t" ,a[i]);
         if (i==4){  //输出换行
         
         printf( "\n" );
         }
         }
 
     return  0;
}

python做选择排序

1
2
3
4
5
6
7
8
9
# 扫描无序区,从无序区中找出一个极端值,放入有序区
def  select_sort(li):  # 选择
     for  in  range ( len (li) - 1 ):  # i表示第几次,有多少元素我就要扫几-1次
         # 找无序区最小值,保存最小值的位置
         min_pos  =  i      # 假设起始值最小,min_pos保存最小值的索引
         for  in  range (i + 1 len (li)):  # 第i趟开始时 无序区:li[i:],自己不与自己比较,所以i+1
             if  li[j] < li[min_pos]:  # 满足条件,我存的值比后面的值大,则把后面的值的所以设置为最小值索引
                 min_pos  =  j
         li[min_pos], li[i]  =  li[i], li[min_pos]  # 交换两个值的位置

冒泡排序

每次比较相邻的两个数,将最小的数(从小到大排序)排在较大的数前面.

经过一次排序之后最小的数到达了最前面的位置,并将其他的数字依次向后移动,第二次排序时,将从第二个数开始最小的数移动到第二的位置,依次类推

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
#include <stdio.h>
  
int  main( int  argc,  char  *argv[])
{
     int  i,j;
     int  a[10];
     int  temp;
     printf( "为数组元素赋值\n" );
     for (i=0;i<10;i++){
         printf( "a[%d]=" ,i);
         scanf( "%d" ,&a[i]);
     }
     for (i=1;i<10;i++){ //外层循环1~9这9个元素
         for (j=9;j>=i;j--){ //从后向前循环i后面的元素
         if (a[j]<a[j-1]){ //前面的数大于后面的数,交换
             temp=a[j-1];
             a[j-1]=a[j];
             a[j]=temp;
             }
         }
     }
     
     // 输出数组
     for (i=0;i<10;i++){
         printf( "%d\t" ,a[i]);
         if (i==4){  //输出换行
         
         printf( "\n" );
             }
         }
     return  0;
}

python做冒泡排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 冒泡排序,一遍遍扫描未归位区,比较相邻的两个数字,满足条件则交换,每次使一个元素归位
 
def  bubble_sort(li):  # 冒泡
     for  in  range ( len (li) - 1 ):  # i表示第几次,有多少元素我就要扫几-1次
         for  in  range ( len (li) - i - 1 ):  # 比较元素的位置,len(li)-1-i是未归位区的最大索引
             if  li[j] > li[j + 1 ]:  # 满足条件 将两个数值交换,这里是前面比后面大
                 li[j], li[j + 1 =  li[j + 1 ], li[j]
 
 
def  bubble_sort_1(li):  # 优化冒泡
     for  in  range ( len (li) - 1 ):  # i表示第几次,有多少元素我就要扫几次
         exchange  =  False  # 增加了一个标志位,如果依次循环中没有发生交换,则顺序已经是有序的了,可以直接退出
         for  in  range ( len (li) - i - 1 ):  # 比较元素的位置,len(li)-1-i是未归位区的最大索引
             if  li[j] > li[j + 1 ]:
                 li[j], li[j + 1 =  li[j + 1 ], li[j]
                 exchange  =  True
         if  not  exchange:
             return

插入排序

插入排序就像是摸扑克,第一张算是有序区,从后面的无序区拿扑克向有序区中插

python

1
2
3
4
5
6
7
8
9
10
def  insert_sort(li):   # 插入
     for  in  range ( 1 len (li)):  # i是摸到的牌的下标,第一个属于有序区,所以从第二个开始
         tmp  =  li[i]  # 手里牌的大小
         =  -  1  # j是手里最后一张牌的下标
         # 如果tmp大于我手里第j个元素,他就应该放在第j个位置上,如果小于就继续向前比较
         while  j > =  0  and  li[j] > tmp:    # 两个终止条件:j小于0表示tmp是最小的 顺序不要乱
             # 因为保存了i索引位置的值,所以大于tmp的数都向后移动一位,j自减
             li[j + 1 =  li[j]
             - =  1
         li[j + 1 =  tmp

快速排序

快排采用的递归的思路
是以一个数字为基准(第0个元素),将列表分为大于他的和小于他的两部分,递归进行直至列表少于一个元素

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
def  partition(li, left, right):  # 归位
     # randi = random.randint(left, right)
     # li[randi], li[left] = li[left], li[randi]
     '''
     将一个列表分成左右两部分
     :param li: 列表
     :param left: 开始索引
     :param right: 结束索引
     :return: 返回中间索引
     '''
     tmp  =  li[left]  # 取最左边的值,作为中间值
     while  left < right:  # 左索引一定要小于右索引,
         while  left < right  and  li[right] > =  tmp:
             # 从后向前找一个小于tmp的元素,找不到就将索引-1向前找
             # = tmp可以使right的值是tmp左边的索引
             right  - =  1
         li[left]  =  li[right]  # 找到之后放到最左边 ,此时right位置的值有两个,
         while  left < right  and  li[left] < =  tmp:
             # 在从前往后找一个比tmp大的,找不到就将索引+1向后找
             # = tmp可以使right的值是tmp右边的索引
             left  + =  1
         li[right]  =  li[left]  # 找到之后放到right位置,
     # 当左右索引位置重合时循环结束
     li[left]  =  tmp
     return  left
 
 
def  _quick_sort(li, left, right):  # 递归
     if  left < right:     # 至少两个元素
         mid  =  partition(li, left, right)  # 取中间索引,将两面进行递归
         _quick_sort(li, left, mid  -  1 )
         _quick_sort(li, mid  +  1 , right)

归位图解

 

选择排序

每次选择所要排序得数组中的最大值(由大到小排序,由小到大排序则选择最小值)的数组元素,将这个数组元组的值与最前面没有排序的数组元素进行交换,

第一次排序之后,最大的数字来到了第一位,再从第二个元素开始找,找到最大的元素,与第二个交换位置

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
#include <stdio.h>
 
int  main( int  argc,  char  *argv[])
{
     int  i,j;
     int  a[10];
     int  temp;
     int  index;
     printf( "为数组元素赋值\n" );
     for (i=0;i<10;i++){
         printf( "a[%d]=" ,i);
         scanf( "%d" ,&a[i]);
     }
     for (i=0;i<9;i++){ //外层循环0~8这9个元素
         temp=a[i];  //假设最大值
         index=i;  // 记录假设最大值索引
         for (j=i+1;j<10;j++){ // 内层循环,排序后的元素
             if (a[j]>temp){ //取最大值
                 temp=a[j];  //重置最大值
                 index=j;  //重置最大值索引
             }
         }
         // 交换元素位置
         a[index]=a[i];
         a[i]=temp;
     }
     
     // 输出数组
     for (i=0;i<10;i++){
         printf( "%d\t" ,a[i]);
         if (i==4){  //输出换行
         
         printf( "\n" );
         }
         }
 
     return  0;
}

python做选择排序

1
2
3
4
5
6
7
8
9
# 扫描无序区,从无序区中找出一个极端值,放入有序区
def  select_sort(li):  # 选择
     for  in  range ( len (li) - 1 ):  # i表示第几次,有多少元素我就要扫几-1次
         # 找无序区最小值,保存最小值的位置
         min_pos  =  i      # 假设起始值最小,min_pos保存最小值的索引
         for  in  range (i + 1 len (li)):  # 第i趟开始时 无序区:li[i:],自己不与自己比较,所以i+1
             if  li[j] < li[min_pos]:  # 满足条件,我存的值比后面的值大,则把后面的值的所以设置为最小值索引
                 min_pos  =  j
         li[min_pos], li[i]  =  li[i], li[min_pos]  # 交换两个值的位置

冒泡排序

每次比较相邻的两个数,将最小的数(从小到大排序)排在较大的数前面.

经过一次排序之后最小的数到达了最前面的位置,并将其他的数字依次向后移动,第二次排序时,将从第二个数开始最小的数移动到第二的位置,依次类推

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
#include <stdio.h>
  
int  main( int  argc,  char  *argv[])
{
     int  i,j;
     int  a[10];
     int  temp;
     printf( "为数组元素赋值\n" );
     for (i=0;i<10;i++){
         printf( "a[%d]=" ,i);
         scanf( "%d" ,&a[i]);
     }
     for (i=1;i<10;i++){ //外层循环1~9这9个元素
         for (j=9;j>=i;j--){ //从后向前循环i后面的元素
         if (a[j]<a[j-1]){ //前面的数大于后面的数,交换
             temp=a[j-1];
             a[j-1]=a[j];
             a[j]=temp;
             }
         }
     }
     
     // 输出数组
     for (i=0;i<10;i++){
         printf( "%d\t" ,a[i]);
         if (i==4){  //输出换行
         
         printf( "\n" );
             }
         }
     return  0;
}

python做冒泡排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 冒泡排序,一遍遍扫描未归位区,比较相邻的两个数字,满足条件则交换,每次使一个元素归位
 
def  bubble_sort(li):  # 冒泡
     for  in  range ( len (li) - 1 ):  # i表示第几次,有多少元素我就要扫几-1次
         for  in  range ( len (li) - i - 1 ):  # 比较元素的位置,len(li)-1-i是未归位区的最大索引
             if  li[j] > li[j + 1 ]:  # 满足条件 将两个数值交换,这里是前面比后面大
                 li[j], li[j + 1 =  li[j + 1 ], li[j]
 
 
def  bubble_sort_1(li):  # 优化冒泡
     for  in  range ( len (li) - 1 ):  # i表示第几次,有多少元素我就要扫几次
         exchange  =  False  # 增加了一个标志位,如果依次循环中没有发生交换,则顺序已经是有序的了,可以直接退出
         for  in  range ( len (li) - i - 1 ):  # 比较元素的位置,len(li)-1-i是未归位区的最大索引
             if  li[j] > li[j + 1 ]:
                 li[j], li[j + 1 =  li[j + 1 ], li[j]
                 exchange  =  True
         if  not  exchange:
             return

插入排序

插入排序就像是摸扑克,第一张算是有序区,从后面的无序区拿扑克向有序区中插

python

1
2
3
4
5
6
7
8
9
10
def  insert_sort(li):   # 插入
     for  in  range ( 1 len (li)):  # i是摸到的牌的下标,第一个属于有序区,所以从第二个开始
         tmp  =  li[i]  # 手里牌的大小
         =  -  1  # j是手里最后一张牌的下标
         # 如果tmp大于我手里第j个元素,他就应该放在第j个位置上,如果小于就继续向前比较
         while  j > =  0  and  li[j] > tmp:    # 两个终止条件:j小于0表示tmp是最小的 顺序不要乱
             # 因为保存了i索引位置的值,所以大于tmp的数都向后移动一位,j自减
             li[j + 1 =  li[j]
             - =  1
         li[j + 1 =  tmp

快速排序

快排采用的递归的思路
是以一个数字为基准(第0个元素),将列表分为大于他的和小于他的两部分,递归进行直至列表少于一个元素

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
def  partition(li, left, right):  # 归位
     # randi = random.randint(left, right)
     # li[randi], li[left] = li[left], li[randi]
     '''
     将一个列表分成左右两部分
     :param li: 列表
     :param left: 开始索引
     :param right: 结束索引
     :return: 返回中间索引
     '''
     tmp  =  li[left]  # 取最左边的值,作为中间值
     while  left < right:  # 左索引一定要小于右索引,
         while  left < right  and  li[right] > =  tmp:
             # 从后向前找一个小于tmp的元素,找不到就将索引-1向前找
             # = tmp可以使right的值是tmp左边的索引
             right  - =  1
         li[left]  =  li[right]  # 找到之后放到最左边 ,此时right位置的值有两个,
         while  left < right  and  li[left] < =  tmp:
             # 在从前往后找一个比tmp大的,找不到就将索引+1向后找
             # = tmp可以使right的值是tmp右边的索引
             left  + =  1
         li[right]  =  li[left]  # 找到之后放到right位置,
     # 当左右索引位置重合时循环结束
     li[left]  =  tmp
     return  left
 
 
def  _quick_sort(li, left, right):  # 递归
     if  left < right:     # 至少两个元素
         mid  =  partition(li, left, right)  # 取中间索引,将两面进行递归
         _quick_sort(li, left, mid  -  1 )
         _quick_sort(li, mid  +  1 , right)

归位图解

 

猜你喜欢

转载自www.cnblogs.com/QQ279366/p/8963561.html