交换排序
1.冒泡排序
算法思想
1.将所有元素放入数组中;
2.从第一个元素开始,依次将相邻的两个元素比较,若前者大于后者则交换;
3.重复第2步,直到没有交换为止。
程序实现
void sort(int *a, int n) { int i, j, t, ok; for(i=0; i<n-1; i++){ ok=1; for(j=0; j<n-1-i; j++) if(a[j]>a[j+1]){ t=a[j]; a[j]=a[j+1]; a[j+1]=t; ok=0; } if(ok) break; } }
void sort(int a[], int n) { int i, t, ok; if(n==1) reurn; else{ for(i=0;i<n-1;i++) if(a[i]>a[i+1]){ t=a[i]; a[i]=a[i+1]; a[i+1]=t; ok=0; } if(ok) return; else sort(a,n-1); } }
2.交换排序的另一种方法
void sort(int temp_array[ ],int n) { int i,j,t; for(i=0;i<n-1;i++) for(j=i+1;j<n;j++) if(temp_array[i]> temp_array[j]){ t=temp_array[i]; temp_array[i]=temp_array[j]; temp_array[j]=t; } }
选择排序
算法思想
记住每趟比较中最小的数据下标,最后将最小元素与起始元素交换,这样每趟只交换一次。
程序实现
void sort(int temp_array[ ],int n) { int i,j,point,t; for(i=0;i<n-1;i++){ point=i; for(j=i+1;j<n;j++) if(temp_array[point]> temp_array[j])
point=j; if(point!=i){ t=temp_array[point]; temp_array[point]=temp_array[i]; temp_array [i]=t; } } }
插入排序
算法思想
1.新建一个空列表,用于保存有序数列;
2.从原数列取出一个数插入有序列表中,使其仍保持有序状态;
3.重复第2步,直至原数列为空。
程序实现
void sort(int a[],int n) { int i,j,t; for(i=1;i<n;i++){ t=a[i]; //第i+1个数 for(j=i-1;a[j]>t&&j>=0;j--) //第j个数小于t或所有数都大于t a[j+1]=a[j]; //大于t的数向后挪动 a[j+1]=t; //将t插入第j+1位置 } }
查找算法
1.线性查找法:时间复杂度O(n)级
for(i=0;i<ARRAY_NUM;i++) if(x[i]==key) { m=i; break; } if(m!=-1)
printf(“found! %d”,m); else
printf(“not found!”);
2.折半查找法:时间复杂度O(log2n)级
while(low<=high){ mid=(low+high)/2; if(a[mid]==key){ k=mid; break; } if(key<a[mid]) high=mid-1; else low=mid+1; }
int search(int x[ ],int low,int high,int key) { int mid; mid=(low+high)/2; if(x[mid]==key) return mid; if(low>=high) return –1; else if(key<x[mid]) return search(x,low,mid-1,key); else return search(x,mid+1,high,key); }
3.两路归并法:将两个升序数组合并为一个升序数组,可以将其中一个数组的元素插入另一个数组中。
算法思想
1.定义数组,使其大小为两个序列长度之和;
2.设定两个变量,分别表示两个已经排序的序列起始位置下标;
3.比较两个变量所指的元素,选择较小的元素放入合并空间,增加变量值到下一位置下标;
4.重复第3步,直到某一变量达到序列尾;
5.将另一序列所剩所有元素复制到合并序列尾。
程序实现
#include<stdio.h> int main() { int a1[3] = {5, 9, 19}, a2[5] = {12, 24, 26, 37, 48}, dest[20], i = 0, j = 0, k = 0; while(i<3&&j<5) if(a1[i]>a2[j]) dest[k++] = a2[j++]; else dest[k++] = a1[i++]; while(i<3) dest[k++] = a1[i++]; while(j<5) dest[k++] = a2[j++]; for (i = 0; i < k;i++) printf("%3d", dest[i]); return 0; }
4.大数乘法
算法思想
对于乘法计算,当数值较大时会产生溢出。可以使用3个整型数组a1[LEN]、a2[LEN]、a3[2 * LEN]分别储存两个乘数和积,其中LEN为乘数的位数。
程序实现
#include<stdio.h> #define LEN 10 int input_num(int *a); int max_mul(int *a1, int *a2, int *ret); int main() { int a1[LEN] = {0}, a2[LEN] = {0}; int a3[LEN * 2] = {0}; int i; printf("输入%d位乘数1:", LEN); if(input_num(a1)==-1) return -1; printf("输入%d位乘数2:", LEN); if(input_num(a2)==-1) return -1; printf("乘积:"); if(max_mul(a1,a2,a3)==0) printf("0"); else{ for (i = 2 * LEN - 1; !a3[i] && i >= 0;i--); for (; i >= 0;i--) printf("%d", a3[i]); } return 0; } int input_num(int *a) { int i = -1, j; char c; while((c=getchar())!='\n'){ i++; if(i==LEN){ printf("not legal!\n"); return -1; } for (j = i; j > 0;j--) a[j] = a[j - 1]; a[0] = c - '0'; } return 0; } int max_mul(int *a1,int *a2,int *ret) { int i, j, t, ret_pos, add, a1_end, a2_end; for (j = LEN - 1; !a1[j] && j >= 0;j--); for (i = LEN - 1; !a1[i] && i >= 0;i--); if(i<0||j<0) return 0; a1_end = j; a2_end = i; for (i = 0; i <= a1_end;i++){ add = 0; ret_pos = i; for (j = 0; j <= a2_end || add;j++){ if(j<LEN) t = ret[ret_pos] + a1[j] * a2[i] + add; else t = ret[ret_pos] + add; ret[ret_pos++] = t % 10; add = t / 10; } } return 1; }
实例
1.根据要求编写函数
#include<stdio.h> int Del_findgcd(int a[], int n, int *f); int main() { int a[] = {6, 8, 9, 11, 12, 13, 15, 16, 18, 19}; int cnt = 0, n = 10, gcd = 0, i = 0; cnt = Del_findgcd(a, n, &gcd); for (; i < cnt;i++) printf("%d ", a[i]); printf(",max common divisor is %d", gcd); return 0; } int Del_findgcd(int a[], int n, int *f) { int i = 1, j = 2, r = 0, x = 0, y = 0, k, cnt = 0; for (; i <= (n/2.0+0.5);i++,j+=2){ a[i] = a[j]; cnt++; } x = a[0]; y = a[1]; while((r=x%y)!=0){ x = y; y = r; } for (k = 2; k < cnt;k++){ x = a[k]; while((r=x%y)!=0){ x = y; y = r; } } *f = y; return cnt; }
2. 折半查找法查找一个数
#include<stdio.h> int main() { int a[10] = {5, 23, 28, 34, 43, 45, 56, 60, 67, 90}; int low = 0, high = 9, x = 0, k = 0; int mid = (low + high) / 2; printf("input a number:"); scanf("%d", &x); while(low<=high){ mid = (low + high) / 2; if(a[mid]==x){ k = mid; break; } if(x<a[mid]) high = mid - 1; else low = mid + 1; } if(low<=high) printf("%d", k); else printf("not found"); return 0; }
3.按要求编写函数
#include<stdio.h> #include<math.h> #define array 10 int mpsort(int x[], int n); int prime(int x); int main() { //int x[] = {8, 25, 128, 87, 54, 137, 23, 96, 165, 4}; int num = 0, i = 0; int x[array]; for (; i < array;i++) scanf("%d", &x[i]); num = mpsort(x, array); for (i = 0; i < array; i++) printf("%d ", x[i]); printf("\nt=%d", num); } int mpsort(int x[],int n) { int i, j, point1 = 0, point2, num, t, ok, k = 0; for (i = 0; (i<n)&&(point1==0);i++) if((x[i]%2)==0) point1 = i; for (; i < n;i++) if((x[i]%2==0)&&x[i]>x[point1]) point1 = i; for (j = n - 1; j >= 0;j--) if(prime(x[j])){ point2 = j; break; } num = point2 - point1 + 1; for(i=point1; i<point2; i++,k++){ ok=1;//k=p2-p1-1 for(j=point1; j<point2-k; j++) if(x[j]>x[j+1]){ t=x[j]; x[j]=x[j+1]; x[j+1]=t; ok=0; } if(ok) break; } return num; } int prime(int x) { int prime=1,i; if(x<2) return 0; if(x==2) return 1; for(i=2;i<=sqrt(x)&′i++) if(x%i==0) prime=0; return prime; }
4.合并数组
#include<stdio.h> #define a_num 10 #define b_num 10 int com(int *a, int na, int *b, int nb, int *c); int main() { int a[] = {3, 6, 7, 18, 23, 33, 35, 43, 48, 78}; int b[] = {2, 7, 13, 21, 33, 37, 48, 50, 58, 67}; int c[a_num+b_num], cnt = 0, i = 0; cnt = com(a, a_num, b, b_num, c); for (i = 0; i < a_num + b_num - cnt * 2; i++) printf("%d ", c[i]); printf("\ncount=%d", cnt); } int com(int *a, int na, int *b, int nb, int *c) { int i = 0, j = 0, k = 0, cnt = 0; while(i<na&&j<nb){ if(a[i]>b[j]) c[k++] = b[j++]; else if(a[i]<b[j]) c[k++] = a[i++]; else{ a[i++] = b[j++]; cnt++; } } while(i<na) c[k++] = a[i++]; while(j<nb) c[k++] = b[j++]; return cnt; }