​ ​

排序算法——以PTA例题为例

前言

pta上有一道题目是要求用“选择法排序”的方法来排序。
我对排序还是不太了解,借此用冒泡,选择,插入法来解决这道题目,加深对排序的理解。

正文

题目

本题要求将给定的n个整数从大到小排序后输出

输入样例:

4
5 1 7 6

输出样例:

7 6 5 1

冒泡排序

从前向后(或从后向前)依次比较相邻两个元素的大小,如果逆序(与题意要求的顺序相反)就进行交换,使最小(最大)的元素上浮(下沉)到本次排序的最前面(最后面),从而完成一趟(pass)排序。下一趟排序时,已经有序的元素不再参与。这样的话,n个元素需要进行n-1趟排序
第一趟:参与数字序列:5 1 7 6

  • 第一个数5和第二个数1比较,顺序不变。5 1 7 6
  • 第二个数1和第三个数7比较,逆序,交换位置。5 7 1 6
  • 第三个数1和第四个数6比较,逆序,交换位置。5 7 6 1

第二趟:参与数字序列:5 7 6
..............
类似经过n-1趟排序后:7 6 5 1

代码:

#include <stdio.h>
#define MAX 100
int main(){
	int i,j,s[MAX],n,t;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&s[i]);
	}
	for(i=0;i<n;i++){//外层循环表示排序的趟数,N个数总共进行N-1趟排序
		for(j=1;j<n;j++){//内层循环表示每一趟参与排序的数字 
			if(s[j]>s[j-1]){
				t=s[j-1];
				s[j-1]=s[j];
				s[j]=t;
			}
		}
	}
	printf("%d",s[0]);
	for(i=1;i<n;i++)
	   printf(" %d",s[i]);
} 

选择排序

找到当前数字序列中最大(最小)的数,记录其所在位置,将其和最前面(最后面)的数进行交换,使最小(最大)的元素上浮(下沉)到本次排序的最前面(最后面),从而完成一趟(pass)排序。下一趟排序时,已经有序的元素不再参与。这样的话,n个元素需要进行n-1趟排序
第一趟:参与数字序列:5 1 7 6

  • 该数字序列中最大的数7,记录其所在位置,将其和第一个位置的数5进行比较,7大于5,所以7和5交换,得到新的序列(7) 1 5 6

第二趟:参与数字序列:1 5 6

  • 该数字序列中最大的数6,记录其所在位置,将其和第一个位置的数1进行比较,6大于1,所以6和1交换,得到新的序 (7 6) 5 1

第三趟:参与数字序列:5 1
排序不变,最终得到最后序列 7 6 5 1.

代码:

#include <stdio.h>
#define MAX 100
int main(){
	int n,i,j,pos,s[MAX],t;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&s[i]);
	}
	for(i=0;i<n-1;i++){
		pos=i;
		for(j=i+1;j<n;j++){ 
		    if(s[j]>s[pos])
		      pos=j;//最大元素的下标 
		}
			if(pos!=i){//当找到的最大数字的位置发生变化的时候,才交换两个数的位置 (可加,可不加)
				t=s[pos];//调换顺序 
				s[pos]=s[i];
				s[i]=t;
			}
	}
	 printf("%d",s[0]);
	for(i=1;i<n;i++)
	   printf(" %d",s[i]);
}

插入排序

将数组的第一个数认为是有序数组,从后往前(从前往后)扫描该有序数组,把数组中其余n-1个数,根据数值的大小,插入到有序数组中,即通过比较和移动有序数列中的元素,将元素插入到合适的位置直至数组中的所有数有序排列为止。这样的话,n个元素需要进行n-1趟排序
第一趟:参与数字序列:5

  • 从后往前扫描有序数组,将第二个数1和第一个数5进行比较,5比1大,得到新数字序列5 1;

第二趟:参与数字序列:5 1

  • 从后往前扫描有序数组,将第三个数7和第二个数1进行比较,7比1大,将7插入到1的前面,再与第一个数字5比较,7比5大,将7插入到5的前面,得到新数字序列7 5 1;

第三趟:参与数字序列:7 5 1
类似地排序后,得到7 6 5 1

代码:

#include <stdio.h>
#define MAX 100
int main(){
	int i,j,s[MAX],n,t,f;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&s[i]);
	}
	for(i=1;i<n;i++){
		if(s[i]>s[i-1]){
		 t=s[i];//取得较大的数 t
		 f=i;//此数的位置i 
	    for(;f>=1&&t>s[f-1];f--){
	    	s[f]=s[f-1];//小的数往后移 ,直到f=0或者不满足条件t>s[f-1]
		} 
	    s[f]=t;   //安排此数t的位置 
	    }
	}
    printf("%d",s[0]);
	for(i=1;i<n;i++)
	   printf(" %d",s[i]);
} 


浅解,如有错误请指正

posted @ 2020-03-13 16:14  Adeleeeeee  阅读(865)  评论(0)    收藏  举报