交换排序
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;
}
葡萄美酒夜光杯,欲饮琵琶马上催。