第二章
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代码
循环不定式没什么好说的。。看书
伪代码:
缩进表示块结构(脑补一个块两边有大括号)
退出循环后 计数器保持其值
数组下标从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
2.1_3
形式化说明:用一个变量保存进位
用for依次相加结果加上进位
j=n+1
temp=0
for i=n to 1
形式化说明:用一个变量保存进位
用for依次相加结果加上进位
2.2-2
归并排序
2.3-2 无哨兵归并
2.3-3 递归式证明
2.3-4 递归插入排序
2.3_5 二分查找
2.3_6 二分插入排序
2.3_7 存在两数之和
2-1 插入归并
2-3 霍纳原则
2-4 逆序对
在数组中,从第一个数开始 (使得从第一个数到这个数有序) 到最后一个数结束 (这时整个数组有序)
这样问题就转化成时 面对 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; }
相关文章推荐
- SQL SERVER2000教程-第二章-创建和管理数据库 第五节 清空数据库的LOG日志文件
- (连载)边喝咖啡边学Unity——第二章 预备知识体系(2)
- Python黑帽子学习笔记-----第二章
- ppk on JavaScript第二章:背景(完结篇)
- 算法导论 第二章
- 《Linux设备驱动程序》第二章 笔记
- WINDOWS核心编程--第二章UNICODE
- 算法竞赛入门经典_第二章:循环结构程序设计_上机练习_MyAnswer
- 微信小程序教学第二章:小程序中级实战教程之预备篇 - 项目结构设计 |基于最新版1.0开发者工具
- 学习笔记《实战Linux Socket编程》第二章
- 第二章复习整理
- [置顶] 信息学奥赛一本通(C++版) 第一部分 C++语言 第二章 顺序结构程序设计
- Essential Silverlight翻译连载---第二章 续1
- 第二章线性表实验
- 第二章 SQL命令参考-CREATE TYPE
- 视频第二章整理笔记
- 第二章思维导图
- 第二章 SQL命令参考-DECLARE
- DJL语言标准--第二章:命令
- OCP 11g 第二章练习