水一篇
今天主要把论文格式弄完了,感谢沁廷的帮助
然后就写了一下数据结构的实验,顺便看一下冠宏的数据结构作业,写一篇吧
还有,为什么今天不能tab了???导致我这个题解写的很难看,草!
我的数据结构作业
作业真的是so easy(瞎说的)
实验一、
1)针对一个由小到大有序的顺序表,编写程序将其中的重复数据只保留一个,算法时间复杂度为O(n);
例如: 原始表为:3, 5, 5, 5, 5, 7, 8, 8, 8, 9, 9, 11
修改表为:3, 5, 7, 8, 9, 11
/*
实验01 线性表的应用
思路:
由于所给的顺序表是由小到大排序的,因此重复的元素一定相邻
那么就遍历整个线性表,每次遇到新元素就记录一下,如果后面的和它相等就不存进去
可以重新开辟一个数组用来存放元素,然后复制回原数组,不过这样的空间复杂度高
考虑到如果有重复的元素,那么可以设置一个new_len用来记录不重复的元素的个数,这样也不会干扰后面还没有遍历的元素
*/
#include<stdio.h>
#define N 12
int List[N]={1,2,3,4,5,6,7,8,9,10,11,12};
int main(){
int new_len=0;
int element=List[0];//第一个直接放进去
for(int i=1;i<N;i++){
if(List[i]==element){//如果相同
;
}
else{
List[++new_len]=List[i];
}
element=List[i];
}
for(int i=0;i<=new_len;i++)
printf("%d ",List[i]);
return 0;
}
实验二、
题目:(2)针对一个由小到大有序的链表,编写程序将其中的重复数据只保留一个。(选做)
/*
因为之前我自己已经实现了链表的大部分操作,因此直接将那些操作引入进来
重点是对于重复元素的处理
这个思路应该和上一个实验很相似
这里我们对于一个新的,应该添加进去的,方法同实验一,只需要设置一个新元素指针即可
*/
#include<stdio.h>
#include<stdlib.h>
//预定义常量
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;//函数结果状态
typedef int ElemType;//数据元素类型定义,此处选择常用的int,后续可根据数据类型自行更改
//线性表的单链表存储结构(结构指针):
typedef struct LNode{
ElemType data;//数据域
struct LNode*next;//指针域
}LNode,*LinkList;//LNode是struct LNode的别名,LinkList是LNode的指针(LinkList=struct LNode*)
LinkList Create(LinkList head){
head=(LinkList)malloc(sizeof(LNode));//这个作为头指针
LinkList newnode=(LinkList)malloc(sizeof(LNode));
LinkList tmp_node;
head->next=newnode;
ElemType a;scanf("%d",&a);
while(a>0){
newnode->data=a;
tmp_node=newnode;
newnode=(LinkList)malloc(sizeof(LNode));
tmp_node->next=newnode;
scanf("%d",&a);
}
//此时最后一个结构体中没有值,然后如果将null放在这个结构体的指针域不妥
//因此null应该放在前面的那个结构体的指针域中
tmp_node->next=NULL;
return head;
}
int main(){
LinkList head;
printf("测试数据:\n");
head=Create(head);//head已经弄好了
LinkList p;
LinkList newnode;
p=head->next;//p当前指在数据域的第一个
newnode=p;
//第一个肯定留下来,就单独处理
int element;
element=p->data;
p=p->next;
while(p->next){//相当于遍历了,时间复杂度为O(n)
if(element==p->data){//如果是重复的
;
}
else{
newnode=newnode->next;
newnode->data=p->data;
}
element=p->data;
p=p->next;
}
//还有最后一个单独考虑
if(element!=p->data){
newnode=newnode->next;
newnode->data=p->data;
}
newnode->next=NULL;
//可以把后面的结点都free了,但是这个我没写
newnode=head->next;
while(newnode->next){
printf("%d ",newnode->data);
newnode=newnode->next;
}
printf("%d",newnode->data);
return 0;
}
冠宏的数据结构作业
题目一
求最大子列和。设计并实现2种求最大子列和的方法,并分析其算法的时间复杂度。
方法一
- 这个算法复杂度为O(n三次方)
/*
最大子列和
方法一就是遍历就
行了,直接看代码吧,easy
*/
#include<stdio.h>
#include<iostream>
using namespace std;
//方法一:
int main(){
int n;
long long a[2002];
long long ans=-9223372036854775808;
long long tem=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){//序列数的个数
for(int j=1;j<=n-i+1;j++){//从第几个开始遍历
for(int k=j,time=1;time<=i;k++,time++){//具体的遍历过程
tem+=a[k];
}
ans=tem>=ans?tem:ans;
tem=0;
}
}
cout<<ans;
return 0;
}
为什么我感觉法一是对的,但是在oj上测试不对呢,而且我数据都不能全部输入进去,疑惑。
冠宏别用方法一,可能不对
方法二
- 这个是我早晨时候看题解猛然醒悟的方法,其实和方法一 一样,但是我们只需要O(n方)的复杂度就可以了。我真憨,我单知道那个方法拉的一批,我还写。。。
/*
此方法为n方复杂度
*/
#include<iostream>
using namespace std;
int n;
long long a[200002];
long long ans=-9223372036854775807;
long long tem=0;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){//从第几个开始
tem=0;
for(int j=i;j<=n;j++){
tem+=a[j];
ans=tem>=ans?tem:ans;
}
}
cout<<ans;
return 0;
}
这个在OJ上只能过2个,后面超时,说明n方的方法依旧不行
方法三
贪心,直接贴代码
/*
方法三、
本方法是贪心算法:
贪心的思路是
我们遍历,如果当前子序列的和是负数的话,那么果断舍弃重开,因为开头就是负数,我加了岂不是吃亏?
如果当前的和不是负数,那就记录,依旧是用当前的子序列加上新的元素
之前我对这个还有疑惑,但是现在想一下,要是求元素和最大的子序列
如果没有负数的话,岂不是数越多越好??那么如果刚开始的都是正数,那我们就要了
当然如果是负数就类似于上面的方法,我们直接重新开始子序列。
这样的贪心肯定是对的,当然为了确保该子序列最后那些都不是复制,也要设置tem和ans,详见代码,你会懂的
该算法时间复杂度为O(n),效率感人。
*/
#include<iostream>
using namespace std;
int n;
long long a[200002];
long long ans=-92233720368547757;
long long tem=0;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
tem+=a[i];
ans=tem>=ans?tem:ans;
if(tem<0)
tem=0;
}
cout<<ans;
return 0;
}
方法四
DP算法,和贪心好类似啊😌
/*
dp做法
思路:
定义一下:dp[i]表示到第i个能有的最大子序列和
那么在dp[i]处就有继承和重头开始这两个选项
那么就是包含a[i]这里我们要比较一下,加上这个之后的序列和从头开始(a[i])比较,选取一个大的
因为我们希望加后面的话,让前面的基础大一点最好
如果发现加上后整体大,那么就继承
如果发现加上后整体小,那么就重新开始(其实就是和贪心很像,如果前面序列和是负的,那么我们就不要)
猛然惊醒,这不就是贪心算法吗???
*/
#include<iostream>
using namespace std;
long long a[200002];
long long dp[200002];
int n;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
dp[i]=max(dp[i-1]+a[i],a[i]);
}
long long ans;
ans=dp[1];
for(int i=2;i<=n;i++){
ans=dp[i]>ans?dp[i]:ans;
}
cout<<ans;
return 0;
}
好的,不写了,饭饭去了