解题思路:
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分
19 人评分
#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; }
KK 2022-01-24 14:04:36 |
定义了多余的变量忘记删了
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
uq_53496377557 2021-12-10 17:35:46 |
#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; }
为啥不加EOF会显示输出超限??
渴望学到知识的菜鸟 2021-05-03 22:05:42 |
他不输入0 的话,就不会结束,所以会超出限制,你可以试着在你循环里面scanf("%d",&n);的前面加一个n=0;
题目不是说所有值的绝对值不同吗?如果我输入是有些值相同,不是错误吗?
小黑 2020-02-25 22:08:13 |
这道题有问题,我没去重,提交成功了;加一个循环去重,输出超限;
#include<stdio.h> int main() { int s[100],i,n,j,t; while(1) { scanf("%d",&n); if(n==0) break; for(i=0;i<n;i++) scanf("%d",&s[i]); for(i=0;i<n-1;i++) { for(j=0;j<n-1-i;j++) { if(abs(s[j])>abs(s[j+1])) { t=s[j]; s[j]=s[j+1]; s[j+1]=t; } } } for(i=n-1;i>=0;i--) printf("%d ",s[i]); printf("\n"); } return 0; } 哪位大佬帮我看看,超出界限50%,哪错了?
Cccc 2020-01-10 09:56:30 |
#include<stdio.h> #include<math.h> int main() { int n; int a[102]; while(scanf("%d",&n)&&n!=0) { for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<n;i++) { for(int j=0;j<n-i-1;j++) { if(abs(a[j])>abs(a[j+1])) { int t=a[j]; a[j]=a[j+1]; a[j+1]=t; } } } int f=0; for(int i=n-1;i>=0;i--) { printf(f?" %d":"%d",a[i]); f=1; } printf(" "); } return 0; }
菜园啊 2020-06-09 23:19:29 |
这位兄弟输出超限问题可解决? 我们思路一样的 我也是输出超限找不到原因
shijilin1 2020-07-22 11:15:44 |
@zxyi 全部数据输入完再输出就没事了,不要输一组放一组
#include<stdio.h> void sort(int a[],int n){ int i,k,q; for(i=0;i<n;i++){ for(k=0;k<n-i-1;k++){ if((a[k]*a[k]) < (a[k+1]*a[k+1])){ q=a[k]; a[k]=a[k+1]; a[k+1]=q; } } } for(i=0;i<n;i++){ printf("%d ",a[i]); } } int main(){ int n; int a[101]; while(scanf("%d",&n)!=EOF){ int i; for(i=0;i<n;i++){ int t; scanf("%d",&t); a[i]=t; } sort(a,n); printf("\n"); } return 0; } 感觉代码量好多
C语言训练-求s=a+aa+aaa+aaaa+aa...a的值 (C语言代码)浏览:1027 |
C语言程序设计教程(第三版)课后习题7.1 (C语言代码)浏览:724 |
A+B for Input-Output Practice (C++代码)浏览:605 |
回文串 (C语言代码)浏览:2834 |
C语言程序设计教程(第三版)课后习题1.5 (C语言代码)浏览:510 |
大家好,我是验题君浏览:572 |
用筛法求之N内的素数。 (C语言代码)浏览:527 |
分糖果 (C语言代码)浏览:911 |
C语言程序设计教程(第三版)课后习题12.5 (C语言代码)浏览:758 |
字符逆序 (C语言代码)浏览:504 |