原题链接:绝对值排序
解题思路:
1.采用分治法思想,把整个序列,拆分为多个子序列,分别对多个子序列排序,再把排好序的子序列合并起来,具体如图:

拆分过程实现:
void Mesort(int *A,int *B,int left,int right)//B[],用于合并排序时
{
if(left<right) //子序列长度大于一,则继续分
{
int i=(left+right)/2; //求中点
Mesort(A,B,left,i); //左半部分拆分
Mesort(A,B,i+1 ,right); //右半部分拆分
}
}合并加排序实现:
void Merge(int *A,int *B,int left,int middle,int right)
{
int i=left,j=middle+1,k=left; //i为右半部分第一个数的下标,j为左半部分第一个数的下标
//B[]用于存放排好序的序列
while((i<=middle)&&(j<=right)) //左右两部分同时遍历
{
if(fabs(A[i])>=fabs(A[j])) //把左右两部分的绝对值大的存入B[]
B[k++]=A[i++];
else
B[k++]=A[j++];
}
//这里把剩余部分存到B[]里,因为每一个子序列都是排好序的,直接存放就可
if(i>middle)
for(int q=j;q<=right;q++) //左半部分序列有剩余
B[k++]=A[q];
else
for(int q=i;q<=middle;q++) //右半部分序列有剩余
B[k++]=A[q];
}
把排好序的部分B[],复制回A[].
void copy(int *A,int *B,int left,int right)
{
for(;left<=right;left++)
A[left]=B[left];
}完整递归:
void Mesort(int *A,int *B,int left,int right)
{
if(left<right)
{
int i=(left+right)/2;
Mesort(A,B,left,i);
Mesort(A,B,i+1 ,right);
Merge(A,B,left,i,right);
copy(A,B,left,right);
}
}注意:只以0结束的话,提交会输出超限,得加上以文件末尾结束
参考代码:
#include <stdio.h>
#include <malloc.h>
#include <math.h>
void input( int *A, int n );
void output( int *A, int n );
void Mesort( int *A, int *B, int left, int right );
void Merge( int *A, int *B, int left, int middle, int right );
void copy( int *A, int *B, int left, int right );
/*--------------------------------------------------------*/
int main()
{
int *A, *B;
int n;
while ( scanf( "%d", &n ) != EOF && n != 0 )
{
A = (int *) malloc( n * sizeof(int) );
B = (int *) malloc( n * sizeof(int) );
input( A, n );
Mesort( A, B, 0, n - 1 );
output( A, n );
free( A );
free( B );
}
return(0);
}
/*--------------------------------------------------------*/
void Mesort( int *A, int *B, int left, int right )
{
if ( left < right )
{
int i = (left + right) / 2;
Mesort( A, B, left, i );
Mesort( A, B, i + 1, right );
Merge( A, B, left, i, right );
copy( A, B, left, right );
}
}
/*--------------------------------------------------------*/
void Merge( int *A, int *B, int left, int middle, int right )
{
int i = left, j = middle + 1, k = left;
while ( (i <= middle) && (j <= right) )
{
if ( fabs( A[i] ) >= fabs( A[j] ) )
B[k++] = A[i++];
else
B[k++] = A[j++];
}
if ( i > middle )
for ( int q = j; q <= right; q++ )
B[k++] = A[q];
else
for ( int q = i; q <= middle; q++ )
B[k++] = A[q];
}
/*--------------------------------------------------------*/
void copy( int *A, int *B, int left, int right )
{
for (; left <= right; left++ )
A[left] = B[left];
}
/*-------------------------*/
void input( int *A, int n )
{
for ( int i = 0; i < n; i++ )
scanf( "%d", &A[i] );
}
/*-------------------------*/
void output( int *A, int n )
{
for ( int i = 0; i < n - 1; i++ )
printf( "%d ", A[i] );
printf( "%d\n", A[n - 1] );
}别忘点赞哦-.-
附带一个选择排序实现:详解见1129题(在选择排序基础上加上个绝对值)
#include <stdio.h>
#include <malloc.h>
#include <math.h>
void sort( int n );
void input( int *A, int n );
void output( int *A, int n );
/*----------------------------------------------------*/
int main()
{
int n;
while ( scanf( "%d", &n ) != EOF && n != 0 )
sort( n );
return(0);
}
/*----------------------------------------------------*/
void sort( int n )
{
int *A;
int maxi, term;
A = (int *) malloc( n * sizeof(int) );
input( A, n );
for ( int i = 0; i < n; i++ )
{
maxi = i;
for ( int j = i; j < n; j++ )
{
if ( fabs( A[maxi] ) < fabs( A[j] ) )
maxi = j;
}
if ( i != maxi )
{
term = A[i];
A[i] = A[maxi];
A[maxi] = term;
}
}
output( A, n );
return;
}
/*----------------------------------------------------*/
void input( int *A, int n )
{
for ( int i = 0; i < n; i++ )
scanf( "%d", &A[i] );
}
/*----------------------------------------------------*/
void output( int *A, int n )
{
for ( int i = 0; i < n - 1; i++ )
printf( "%d ", A[i] );
printf( "%d\n", A[n - 1] );
}别忘点赞哦-.-
0.0分
17 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
#include<stdio.h> #include<math.h> int main() { int n; while(scanf("%d",&n)&&n) { int a[n]; for(int i=0;i<n;i++) { scanf("%d",&a[i]); } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(abs(a[i])>abs(a[j])) { int temp; temp=a[j]; a[j]=a[i]; a[i]=temp; } } } for(int i=0;i<n;i++) { printf("%d ",a[i]); } printf("\n"); } return 0; }//简单易懂的方法 #include<stdio.h> #include<math.h> int main() { int n; int i,j,k=0; int a[100],b[100]; int c[100]; while( scanf( "%d", &n) != EOF && n != 0)//必须加“!=EOF”,否则超限 { for(i=0;i<n;i++) { scanf("%d",&a[i]); } for(i=0;i<n;i++)//冒泡 { for(j=0;j<n-1;j++) { if(fabs(a[j])<fabs(a[j+1])) { int t=a[j]; a[j]=a[j+1]; a[j+1]=t; } } } for(i=0;i<n;i++) { printf("%d ",a[i]); } printf("\n"); } return 0; }@uq_53496377557 #include<stdio.h> #include<stdlib.h> void maopao(int * arr ,int * signa, int len , int * ARR){ //冒泡排序并显示 for(int i = 0 ; i < len-1 ; i++){ for(int j = 0 ; j < len - 1 - i ; j++ ){ if(arr[j]<arr[j+1]){ int temp; temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; int iii; iii = signa[j]; signa[j] = signa[j+1]; signa[j+1] = iii; } } } for(int i ; i < len - 1 ; i++){ if(signa[i] == 1){ ARR[i] = -1*arr[i]; // printf("%d ",-1*arr[i]); } else{ //printf("%d ",arr[i]); ARR[i] = arr[i];} } // printf(" "); } void abbs(int * arr,int * signa, int len){ for(int i = 0 ; i < len ; i++){ if(arr[i] < 0){ arr[i] = abs(arr[i]); signa[i] = 1; } } } int main() { int chang[101]; int ARR[101][101] ; int m; while(1){ int i,a[100] ;//i是这次序列的长度 int signa[100] = {0}; char c; scanf("%d",&i); if(i == 0) break; chang[m] = i; for(int j = 0 ; j<i ; j++){ scanf("%d%c",&a[j],&c); if(c == ' ') break; } abbs(a,signa,i+1); maopao(a,signa,i+1,ARR[m]); m++; } for(int i = 0 ; i < m ; i++){ for(int j = 0 ; j < chang[i] ; j++){ printf("%d ",ARR[i][j]); } printf(" "); } return 0; }Segmentation fault:段错误,检查是否有数组越界,指针异常,访问到不应该访问的内存区域 但是我用vsc能跑。。 #include<stdio.h> #include<stdlib.h> void maopao(int * arr ,int * signa, int len , int * ARR){ //冒泡排序并显示 for(int i = 0 ; i < len-1 ; i++){ for(int j = 0 ; j < len - 1 - i ; j++ ){ if(arr[j]<arr[j+1]){ int temp; temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; int iii; iii = signa[j]; signa[j] = signa[j+1]; signa[j+1] = iii; } } } for(int i@林某蛋炒饭 他不输入0 的话,就不会结束,所以会超出限制,你可以试着在你循环里面scanf("%d",&n);的前面加一个n=0;