您的位置:首页 > 其它

第二章

2015-04-03 16:26 113 查看
插入排序原理:

  在数组中,从第一个数开始 (使得从第一个数到这个数有序) 到最后一个数结束 (这时整个数组有序)

  这样问题就转化成时 面对 1个已经有序的数组(n个数) 在它后面再加一个数 使得这整个数组(n+1个数)有序

  解决这一问题的方法是 将这个第n+1个数插入到前面的数组中 就像打牌的时候 你之前的牌已经排好了 有摸到一张牌 你把他插到两张牌中间 使得这三张牌有序 你手里的牌必然是有序的

  伪代码:

  INSERT_SORT(A)

  for j=2to A.length

    key=A[j]//在已经排好序的数组A[1]~A[j-1]中插入A[j]

    i=j-1

    while(i>0andA[i]>key)

      A[i+1]=A[i]

      i=i-1

    A[i+1]=key

C代码

#include <stdio.h>
void printArray(int A[],int size);
void insertSort(int *a,int size)
{
int key;
int j=1;
for(int i=1;i<size;i++)
{
key=a[i];
j=i-1;
while(j>=0&&key<a[j])
{
a[j+1]=a[j];
j--;
}
a[j+1]=key;
}
}

int main()
{
int arr[10]={9,8,7,6,5,4,3,2,1,0};
printArray(arr,10);

insertSort(arr,10);

printArray(arr,10);

return 0;
}

void printArray(int A[],int size)
{    int i;
for(i=0;i<size;i++)
{
printf(" %d ",A[i]);
}
printf("\n-------------------\n");
}


循环不定式没什么好说的。。看书

伪代码:

缩进表示块结构(脑补一个块两边有大括号)

退出循环后 计数器保持其值

数组下标从1开始(c c++ java 从0开始) A[n..m]表示数组A
,A[n+1]~~A[m]

对于复合数据类型 如 struct x{int y;int z} 用x.f 对f进行操作 y=x意味着同类型的y的所有值和x一样

return 可以返回多个值

and or 相当于 && || 都是短路运算符

2.1-1 太丑了 就不贴了+_+

2.1-2

#include <stdio.h>
void printArray(int A[],int size);
void insertSort(int *a,int size)
{
int key;
int j=1;
for(int i=1;i<size;i++)
{
key=a[i];
j=i-1;
while(j>=0&&key>a[j])//<-- 只不过把这里的符号改了
{
a[j+1]=a[j];
j--;
}
a[j+1]=key;
}
}

int main()
{
int arr[10]={0,1,2,3,4,5,6,7,8,9};
printArray(arr,10);

insertSort(arr,10);

printArray(arr,10);

return 0;
}

void printArray(int A[],int size)
{    int i;
for(i=0;i<size;i++)
{
printf(" %d ",A[i]);
}
printf("\n-------------------\n");
}


2.1_3

形式化说明:用一个变量保存进位
用for依次相加结果加上进位

j=n+1

temp=0

for i=n to 1

  

形式化说明:用一个变量保存进位
用for依次相加结果加上进位

#include <stdio.h>
void p(int data[],int size)
{
for(int i=0;i<size;i++)
{
printf("%3d",data[i]);
}
printf("\n........................\n");
}
int main()
{
int b1[10]={0,0,0,0,0,0,0,0,0,0};
int b2[10]={1,1,1,1,1,1,1,1,1,1};
int sum[11];
int temp=0;
for(int i=9;i>=0;i--)
{
sum[i+1]=b1[i]+b2[i]+temp;
if(sum[i+1]>1)
{
temp=1;
sum[i+1]%=2;
}
else temp=0;
}
sum[0]=temp;
p(b1,10);
p(b2,10);
p(sum,11);
return 0;
}


2.2-2

#include <stdio.h>

void p(int data[],int size)
{
for(int i=0;i<size;i++)
{
printf(" %d ",data[i]);
}
printf("\n........................\n");
}
void select(int num[],int size)
{
int max,maxi;
for(int i=0;i<size-1;i++)
{
max=num[i];
maxi=i;
for(int j=i+1;j<size;j++)
{
if(num[j]>max)
{
max=num[j];
maxi=j;
}
}
int temp=num[i];
num[i]=num[maxi];
num[maxi]=temp;
}

}

int main()
{
int num[10]={1,23,34,2,32,12,123123,43,12,122};
p(num,10);
select(num,10);
p(num,10);

return 0;
}


归并排序

#include <stdio.h>

const int INFINITE = 999999;

void print(int num[],int s,int e)
{    int i;
for(i=s;i<=e;i++)
{
printf(" %d ",num[i]);
}
printf("\n-------------------\n");
}

void merge(int A[],int p,int q,int r) //p 起始 q 中间  r 终止
{
int n1=q-p+1;//左边 的元素个数
int n2=r-q;//右边   的元素个数 r-(q+1)+1=r-q-1+1=r-q
/*let L[1...n1+1]and R[1...n2+1]be new arrays*/
int L[n1+1];
int R[n2+1];//多一个放哨兵值
int i,j;
for(i=0;i<n1;i++)
{
L[i]=A[p+i];
}
for(j=0;j<n2;j++)
{
R[j]=A[q+j+1];
}
L[n1]=INFINITE;
R[n2]=INFINITE;
i=0;
j=0;
int k;
for(k=p;k<=r;k++)//max为最大值导致出现一方为空另一方还有的情况下继续进行正确的赋值
{
if(L[i]<=R[j])
{
A[k]=L[i];
i++;
}
else
{
A[k]=R[j];
j++;
}
}
}

void merge_sort(int A[],int p,int r)
{
if(p<r)
{
int q=(p+r)/2;
merge_sort(A,p,q);
merge_sort(A,q+1,r);
merge(A,p,q,r);
}
}

int main()
{
int A[10]={1,231,1131,345,13114,363,1212,231346,13,123346};
printf("原数组: ");
print(A,0,9);
merge_sort(A,0,9);
printf("终数组: ");
print(A,0,9);

return 0;
}


2.3-2 无哨兵归并

#include "stdio.h"

#define DataType char

void merger(DataType *A,int s,int m,int e)
{
int n1=m-s+1;
int n2=e-m;
DataType left[n1];
DataType right[n2];
for (int i = 0; i < n1; ++i)
left[i]=A[s+i];
for (int i = 0; i < n2; ++i)
right[i]=A[m+1+i];

int j=0,k=0,t=s;
while(j<n1&&k<n2)//通过 n1 n2 限制 j k
{
if (left[j]<right[k])
{
A[t++]=left[j++];
}
else
{
A[t++]=right[k++];
}
}
while(j<n1)//还剩下的补上
{
A[t++]=left[j++];
}
while(k<n2)//同上
{
A[t++]=right[k++];
}

}

void mergerSort(DataType *A,int s,int e)
{
if (s<e)
{
int mid=(s+e)/2;
mergerSort(A,s,mid);
mergerSort(A,mid+1,e);
merger(A,s,mid,e);
}
}

int main(int argc, char const *argv[])
{

char s[]="qwertyuiopasdfghjklzxcvbnm";
printf("%s\n",s );
mergerSort(s,0,25);
printf("%s\n",s );
return 0;
}


2.3-3 递归式证明



2.3-4 递归插入排序

#include <stdio.h>
void p(int num[],int size)
{    int i;
for(i=0;i<size;i++)
{
printf(" %d ",num[i]);
}
printf("\n-------------------\n");
}

void recu_insert(int A[],int i,int size)
{
if(i>=1)
{
recu_insert(A,i-1,size);
int key=A[i];
int j=i-1;
while(A[j]<key&&j>=0)
{
A[j+1]=A[j];
j--;
}
A[j+1]=key;
}
}

int main()
{
int A[10]={1212,123,13345,134,14,521,435,14415,32,12};
p(A,10);
recu_insert(A,9,10);
p(A,10);

//递归插入排序最坏运行时间   n(n-1)/2+4n;

}


2.3_5 二分查找

#include <stdio.h>
#include "d:/project/c_c++/myfunction.h"
#define p(x,y,z) for(int i=0;i<z;i++){printf(x,y[i]);}printf("\n")

int iteration_binaryFind(int* a,int s,int e,int t)
{
int mid;
while(s<=e)
{
mid=s+(e-s)/2;
if(a[mid]>t)
{
e=mid-1;
}
else if(a[mid]<t)
{
s=mid+1;
}
else return mid;
}
return -1;
}

int recu_binaryFind(int *a,int s,int e,int t)
{
int mid=s+(e-s)/2;
if(a[mid]>t)
return recu_binaryFind(a,s,mid-1,t);
if(a[mid]<t)
return recu_binaryFind(a,mid+1,e,t);
return mid;
}

int cmp(const void *a,const void *b)
{
return *(int*)a-*(int*)b;
}

int main()
{
//    freopen("C:\\Users\\cong\\Desktop\\input.txt","r",stdin);
//    freopen("C:\\Users\\cong\\Desktop\\output.txt","w",stdout);

int arr[10]={0,1,2,3,4,5,6,7,8,9};
init(arr,10);
qsort(arr,10,sizeof(int),cmp);
int target=arr[3];

p("%d ",arr,10);

printf("%d\n",iteration_binaryFind(arr,0,9,target));

printf("%d",recu_binaryFind(arr,0,9,target));

return 0;
}


2.3_6 二分插入排序

#include <stdio.h>
#include "d:/project/c_c++/myfunction.h"
#define p(x,y,z) for(int i=0;i<z;i++){printf(x,y[i]);}printf("\n")

//插入排序的前面是已经排好的序的 寻找比t小的数 就相当于寻找t
int binary_find(int *a,int s,int e,int t)//使用循环的二分法   找到小于t的位置
{
int mid;
while(s<e)
{
mid=s+(e-s)/2;
if(a[mid]>t)
e=mid-1;
else if(a[mid]<t)
s=mid+1;
}
if(a[s]>t)return s; //当前位置的数 大于t 说明t就插入在这个位置
return s+1;//t插入在这个位置的后面
}

void insert_sort(int *a,int size)
{
int key;
int k;
for(int i=1;i<size;i++)
{
key=a[i];
k= binary_find(a,0,i-1,key);//之前通过while循环中 a[j]>key 来确定是否插入到当前点 之后现在直接找到插入点
for(int j=i-1;j>=k;j--)
{
a[j+1]=a[j];
}
a[k]=key;
}
}

int main()
{
//    freopen("C:\\Users\\cong\\Desktop\\input.txt","r",stdin);
//    freopen("C:\\Users\\cong\\Desktop\\output.txt","w",stdout);
int arr[10];
init(arr,10);
p("%d ",arr,10);
insert_sort(arr,10);
p("%d ",arr,10);

return 0;
}


2.3_7 存在两数之和

#include <stdio.h>
#include "d:/project/c_c++/myfunction.h"
#define p(x,y,z) for(int i=0;i<z;i++){printf(x,y[i]);}printf("\n")

int cmp(const void*a,const void *b)
{
return *(int *)a-*(int *)b;
}

int find(int *arr,int s,int e,int key)
{
int mid;
while(s<e)
{
mid=s+(e-s)/2;
if(arr[mid]>key)
{
e=mid-1;
}
else if(arr[mid]<key)
{
s=mid+1;
}
else return mid;
}
return -1;
}
void solve(int*arr,int size,int sum)
{
qsort(arr,10,sizeof(int),cmp);
for(int i=0;i<size;i++)
{
int t=find(arr,0,10,sum-arr[i]);
if(t!=-1)
printf("%d+%d=%d\n",arr[i],arr[t],sum);
}
}
int isExist(int*arr,int size,int sum)
{
qsort(arr,10,sizeof(int),cmp);
for(int i=0;i<size;i++)
{
int t=find(arr,0,10,sum-arr[i]);
if(t!=-1)return 1;
}
return 0;
}

int main()
{
//    freopen("C:\\Users\\cong\\Desktop\\input.txt","r",stdin);
//    freopen("C:\\Users\\cong\\Desktop\\output.txt","w",stdout);

int arr[10]={1,23,452,44,54,234,3,454,2355,243} ;
printf("%d\n",isExist(arr,10,24));
solve(arr,10,24);
return 0;
}


2-1 插入归并

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define p(x,y,z,w) for(int i=z;i<=w;i++){printf(x,y[i]);}printf("\n--------\n")

const int INFINITE = 999999;
void init(int data[],int size)
{
srand(time(NULL));
int i;
for(i=0;i<size;i++)
{
data[i]=rand()%100;
}
}

void print(int num[],int s,int e)
{    int i;
for(i=s;i<=e;i++)
{
printf(" %d ",num[i]);
}
printf("\n-------------------\n");
}

void insertSort(int *a,int s,int e)
{
for(int i=s+1;i<=e;i++)
{
int key=a[i];
int j=i-1;
while(j>=s&&key<a[j])
{
a[j+1]=a[j];
j--;
}
a[j+1]=key;
}
p("%d ",a,s,e);

}

void merge(int A[],int p,int q,int r) //p 起始 q 中间  r 终止
{

int n1=q-p+1;
int n2=r-q;//右边   的元素个数 r-(q+1)+1=r-q-1+1=r-q
int L[n1+1];
int R[n2+1];
int i,j;
for(i=0;i<n1;i++)
{
L[i]=A[p+i];
}
for(j=0;j<n2;j++)
{
R[j]=A[q+j+1];
}
L[n1]=INFINITE;
R[n2]=INFINITE;
i=0;
j=0;
int k;
for(k=p;k<=r;k++)
{
if(L[i]<=R[j])
{
A[k]=L[i];
i++;
}
else
{
A[k]=R[j];
j++;
}
}
p("%d ",A,p,r);

}
void merge_sort(int A[],int p,int r,int k)
{
if(p+k<r)
{
int mid=(p+r)/2;
merge_sort(A,p,mid,k);
merge_sort(A,mid+1,r,k);
merge(A,p,mid,r);

}
else insertSort(A,p,r); //感觉差不多的样子。。。

}

int main()
{
//        freopen("C:\\Users\\cong\\Desktop\\input.txt","r",stdin);
//    freopen("C:\\Users\\cong\\Desktop\\output.txt","w",stdout);

int N=100;
int A
;
init(A,N);
printf("原数组: ");
print(A,0,N-1);
merge_sort(A,0,N-1,5);
//    insertSort(A,0,9);
printf("终数组: ");
print(A,0,N-1);

//    int A[10]={0,1,2,2,45,67,98,45,2,3};
//    merge(A,1,3,6,3);

return 0;
}


2-3 霍纳原则

#include <cstdio>
#include <cmath>
using namespace std;
#define p(x,y,z) for(int i=0;i<z;i++){printf(x,y[i]);}printf("\n")
int a[7]={1,2,3,4,5,6,7};
int n=7;
//朴素多项式求值 霍纳 法则
int simple_hoener(int x)
{
int sum=0;
for(int i=0;i<=n;i++)
{
sum+=a[i]*pow(x,i);
}
return sum;
}
int hoener(int x)
{
int y=0;
for(int i=n;i>=0;i--)
{
y=a[i]+x*y;
}
}

int main()
{
//    freopen("C:\\Users\\cong\\Desktop\\input.txt","r",stdin);
//    freopen("C:\\Users\\cong\\Desktop\\output.txt","w",stdout);
int a[7]={1,2,3,4,5,6,7};
for(int i=0;i<7;i++){a[i]=i;}

printf("%d %d",simple_hoener(2),hoener(2));
return 0;
}


2-4 逆序对

#include <stdio.h>
#include "d:/project/c_c++/myfunction.h"
#define p(x,y,z) for(int i=0;i<z;i++){printf(x,y[i]);}printf("\n")

#define max 9999999
int num=0;
int merge(int A[],int s,int m,int e)
{
int n1=m-s+1;
int n2=e-m;
int L[n1+1];
int R[n2+1];

for(int i=0;i<n1;i++)
L[i]=A[s+i];

for(int i=0;i<n2;i++)
R[i]=A[m+1+i];
L[n1]=max;
R[n2]=max;

int i=0,j=0;
for(int k=s;k<=e;k++)
{
if(L[i]<=R[j])
{
A[k]=L[i];
i++;
}
else
{
num+=n1-i;
A[k]=R[j];
j++;
}
}

}

int mergeSort(int A[],int s,int e)
{
if(s<e)
{

int mid=s+(e-s)/2;
mergeSort(A,s,mid);
mergeSort(A,mid+1,e);
merge(A,s,mid,e);
}
}

int main()
{
int n=5;
int A[]={2,3,8,6,1};

p(" %d ",A,n);
mergeSort(A,0,n-1);
p(" %d ",A,n);
printf("%d",num);
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: