习题1.8 二分查找
| Position BinarySearch( List L, ElementType X ) |
| { |
| int l,r,mid; |
| l=1; |
| r=L->Last;//注意这里L不要写成l |
| while(l<=r) |
| { |
| mid=(l+r)/2; |
| if(L->Data[mid]<X) l=mid+1;//这里Data不要写成data |
| else if(L->Data[mid]>X) r=mid-1; |
| else return mid; |
| } |
| return NotFound; |
| |
| } |
习题1.9 有序数组的插入
、
注释的几个需要注意的点要养成一下习惯
| bool Insert(List L,ElementType X) |
| { |
| if(L->Last==MAXSIZE-1) return false; |
| |
| for(int i=0;i<=L->Last;i++) |
| { |
| if(L->Data[i]==X) return false; |
| |
| else if(L->Data[i]<X) |
| { |
| for(int j=L->Last;j>=i;j--) |
| { |
| L->Data[j+1]=L->Data[j]; |
| } |
| L->Data[i]=X; |
| L->Last++; |
| break; |
| }else{ |
| |
| if(i==L->Last){ |
| L->Data[i+1]=X; |
| L->Last++; |
| break; |
| } |
| } |
| } |
| return true; |
| } |
习题2.4 递增的整数序列链表的插入
| List Insert(List L,ElementType X) |
| { |
| |
| List s=(List)malloc(sizeof (List)); |
| s->Data=X; |
| List p=L; |
| while( p->Next && X > p->Next->Data) |
| |
| { |
| p=p->Next; |
| } |
| |
| s->Next=p->Next; |
| p->Next=s; |
| |
| return L; |
| } |
| List Insert(List L,ElementType X) |
| { |
| |
| List s,p=L->Next,pre=L; |
| s=(List)malloc(sizeof(List)); |
| s->Data=X; |
| |
| while(p!=NULL &&p->Data<X){ |
| pre=p; |
| p=p->Next; |
| } |
| if(p!=NULL) |
| { |
| pre->Next=s; |
| s->Next=p; |
| } |
| else { |
| pre->Next=s; |
| s->Next=NULL; |
| } |
| return L; |
| } |
习题2.5 两个有序链表序列的合并
| List Merge(List L1,List L2) |
| { |
| List p1=L1->Next; |
| List p2=L2->Next; |
| |
| |
| List L=(List)malloc(sizeof(List)); |
| List p=L; |
| |
| |
| while(p1&&p2) |
| { |
| if(p1->Data <p2->Data) |
| { |
| |
| p->Next=p1; |
| p=p->Next; |
| p1=p1->Next; |
| }else{ |
| p->Next=p2; |
| p=p->Next; |
| p2=p2->Next; |
| } |
| } |
| |
| |
| if(p1!=NULL){ |
| |
| p->Next=p1; |
| } |
| if(p2!=NULL) p->Next=p2; |
| |
| |
| L1->Next=NULL; |
| L2->Next=NULL; |
| return L; |
| |
| } |
实例1.1 最大子列和问题
因为我们只需要得到最大的子列和,那么当sum>0时,不断的去取一个最大值,当sum<0时重新更新sum=0即可,这个最大值便是最大的子列和
| |
| using namespace std; |
| int main() |
| { |
| int n; |
| cin>>n; |
| int maxx=-1,sum=0; |
| for(int i=0;i<n;i++) |
| { |
| int x; |
| cin>>x; |
| if(sum+x<0) sum=0; |
| else{ |
| sum+=x; |
| maxx=max(sum,maxx); |
| } |
| } |
| cout<<maxx; |
| |
| } |
| |
习题2.1 简单计算器
简单是简单,但是注意输入的顺序,不然容易卡半天
| #include<bits/stdc++.h> |
| using namespace std; |
| int main() |
| { |
| int sum=0; |
| char op; |
| cin>>sum>>op; |
| while(op!='=') |
| { |
| int x; |
| cin>>x; |
| if(op=='+') sum+=x; |
| else if(op=='-') sum-=x; |
| else if(op=='*') sum*=x; |
| else if(op=='/') |
| { |
| if(x==0){ |
| cout<<"ERROR"; |
| return 0; |
| } |
| else sum/=x; |
| }else { |
| cout<<"ERROR"; |
| return 0; |
| } |
| |
| cin>>op; |
| } |
| cout<<sum; |
| |
| } |
习题2.2 数组循环左移
这题其实有三个方法
方法1:直接观察结果输出即可
| #include <bits/stdc++.h> |
| using namespace std; |
| int main() |
| { |
| int n,m; |
| cin>>n>>m; |
| m%=n; |
| vector<int>ve(n+1); |
| for(int i=1;i<=n;i++) cin>>ve[i]; |
| cout<<ve[m+1]; |
| for(int i=m+2;i<=n;i++) cout<<" "<<ve[i]; |
| for(int i=1;i<=m;i++) cout<<" "<<ve[i]; |
| |
| } |
方法2:通过每次将N个元素循环位移一次,进行m次这样的循环位移
| #include <bits/stdc++.h> |
| using namespace std; |
| int a[105]; |
| |
| void move(int n) |
| { |
| int temp=a[0]; |
| for(int i=0;i<n-1;i++) a[i]=a[i+1]; |
| a[n-1]=temp; |
| } |
| |
| |
| int main() |
| { |
| int n,m; |
| cin>>n>>m; |
| m%=n; |
| for(int i=0;i<n;i++) cin>>a[i]; |
| for(int i=0;i<m;i++) move(n); |
| cout<<a[0]; |
| for(int i=1;i<n;i++) cout<<" "<<a[i]; |
| } |
方法3:就是通过元素翻转位置比如将1 2 3 4 5 6 7 8翻转为3 2 1 4 5 6 7 8然后按照特定顺序输出即可,这里不给出代码。
习题2.3 数列求和-加强版
常规方法是直接进行加减,但是这样当位数太大的时候是会溢出的,所以采取最优的方法就是在每一位上进行计算,然后把对应的每一位存在数组里,最后再输出每一位。原理其实就是加法的进位
| #include <bits/stdc++.h> |
| using namespace std; |
| #define int long long |
| |
| signed main() |
| { |
| int A,N; |
| cin>>A>>N; |
| if(!N){ |
| cout<<0; |
| return 0; |
| } |
| int S[100005]; |
| memset(S,0,sizeof S); |
| int c=0; |
| for(int i=0;i<N;i++) |
| { |
| |
| c+=A*(N-i); |
| S[i]=c%10; |
| c/=10; |
| } |
| |
| if(c) cout<<c; |
| |
| for(int i=N-1;i>=0;i--) cout<<S[i]; |
| } |
习题3.4 最长连续递增子序列
处理两个子问题1.序列最大长度 2.最终的序列区间的左右端点下标
1.只要当时,我们就去更新当前的最大序列长度,和最终答案的下标即可,开temp,l,r分别来记录当前序列长度、序列当前左端点、序列当前右端点即可,否则temp++,r++
2.注意特别处理一下如果序列直接到达了末尾这种情况
| #include <bits/stdc++.h> |
| using namespace std; |
| int a[100005]; |
| int main() |
| { |
| int n; |
| cin>>n; |
| for(int i=1;i<=n;i++) cin>>a[i]; |
| int ansl=0,ansr=0,maxx=-1,l=1,r=0; |
| int temp=1; |
| for(int i=1;i<=n;i++) |
| { |
| if(a[i]>a[i-1]) |
| { |
| temp++; |
| r++; |
| }else{ |
| if(temp>maxx) |
| { |
| maxx=temp; |
| ansl=l; |
| ansr=r; |
| } |
| temp=1; |
| l=r=i; |
| } |
| } |
| |
| if(temp>maxx){ |
| maxx=temp; |
| ansl=l; |
| ansr=r; |
| } |
| cout<<a[ansl]; |
| for(int i=ansl+1;i<=ansr;i++) cout<<" "<<a[i]; |
| } |
基础实验3-2.2 单链表分段逆转
每K段要进行翻转,也就是相当于进行K次头插法,把每一次头插法的第一个结点,当作下一次头插法的头结点。具体可以看图理解手动模拟。

| void K_Reverse(List L,int K) |
| { |
| List t=L->Next; |
| int cnt=0; |
| while(t){ |
| cnt++; |
| t=t->Next; |
| } |
| |
| List head=L,new,old,tmp,s; |
| |
| |
| |
| |
| |
| for(int i=0;i<cnt/K;i++) |
| { |
| new=head->Next; |
| old=new->Next; |
| s=new; |
| int j=K-1; |
| while(j--) |
| { |
| tmp=old->Next; |
| old->Next=new; |
| new=old,old=tmp; |
| } |
| head->Next=new; |
| s->Next=old; |
| head=s; |
| } |
| |
| |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通