浙大版数据结构习题

一开始写了python版和c++版,才发现速度差距是真的可怕。

1.1 最大子列问题

#include <iostream>
using namespace std;

int main(){
    int sum=0;
    int Maxsum=sum;
    int K,value;
    cin >> K;
    while(K--){
        cin >> value;
        sum += value;
        if(sum > Maxsum){Maxsum = sum;}
        if(sum < 0 ){sum = 0;}
    }
    cout<<Maxsum<<endl;
        
    return 0;
}

1.8 二分查找

/*
#include <iostream> 
using namespace std; 

#define MAXSIZE 10
#define NotFound 0

typedef int ElementType;
typedef int Position;
typedef class LNode *List;
class LNode{
    public:
    ElementType Data[MAXSIZE];
    Position Last;    //线性表最后一个元素位置
};

List ReadInput();   // 从下标为1开始存储,内置
Position BinarySearch(List L,ElementType X); //二分查找
*/
Position BinarySearch(List L,ElementType X){
    Position Left = 1;
    Position Right = L->Last;
    Position mid;
    //线性表是递增有序的
    while(Left < Right){
        mid = (Left+Right)/2;
        if (L->Data[mid] == X) {
            return mid;
        }
        if (L->Data[mid] < X){
            Left = mid+1;   //注意这里取下一个,否则运行超时
        }
        else{
            Right = mid-1;
        }  
    }
    if(L->Data[Right] == X) return Right;
    
    return NotFound;
    
}

/*
int main()
{
    List L;
    ElementType X;
    Position P;

    L = ReadInput();
    scanf("%d", &X);
    P = BinarySearch( L, X );
    printf("%d\n", P);

    return 0;
}
*/

1.9 有序数组插入

bool Insert(List L,ElementType X){
     if (L->Last >= MAXSIZE-1){  //下标为0开始,只有10个,取9
        return false;
    }

    Position Left = 0;
    Position Right = L->Last;
    Position mid;
    int flag ;
   
    while(Left <= Right){
        mid = (Left+Right)/2;
        if(L->Data[mid] == X){
            return false;
        }
        if(L->Data[mid] > X){
            flag =1;
            Left = mid+1;
        }
        else{
            flag = 0;
            Right = mid-1;
        }
    }
    
    if (flag) mid +=1;  //flag 用于判断跳出循环前X与mid的关系。7 5 2  X=(3,6,1)试试
    L->Last+=1;
    Right =L->Last;
    while(mid<Right){
        L->Data[Right] = L->Data[Right-1];
        Right--;
    }
    L->Data[Right] = X;
    return true;
    
}

2.1 简单计算器

#include <iostream>
using namespace std;


int main(){

char oper;
int a;
int ans;

cin>>ans;
while(cin>>oper && oper != '='){
    cin >> a;
    switch (oper)
    {
        case '+':
            ans += a;
            break;
        case '-':
            ans -= a;
            break;
        case '*':
            ans *= a;
            break;
        case '/':
            if(a != 0){
                ans /= a;
                break;     
            }
            else{
                cout<<"ERROR"<<endl;
                return 0;
                break;
            }
        default:
            cout<<"ERROR"<<endl;
            return 0;
            break;
          }    
    }
cout<<ans<<endl;
return 0;
}

2.2 数组循环左移

#include <iostream>
using namespace std;


int main(){
    int n,m,step,i,j=0;
    cin>>n;
    cin>>m;
    step = m%n;  //一共要移动的位数
    int a[n];
    int b[step];  //存放左移动溢出数据
    for(i=0;i<n;i++){
        cin>>a[i];
    }//初始化数组完成
    
    for(i=0;i<step;i++){
        b[i] = a[i];
    }
    
    for(i=n-step;i>0;i--){
        a[j] = a[step+j];
        j++;
    }
    for(i = 0;i<step;i++){
        a[j] = b[i];
        j++;
    }
    
    for(i = 0;i<n-1;i++){
        cout<<a[i]<<" ";
    }
    cout<<a[i]<<endl;
    
    return 0;
}

2.3最大子列和(***) 本题较难,建议先跳过

#include <iostream>
using namespace std;
//这道题是真的难,是浙大考研复试真题。建议先跳过。
#define MAX_N 100000

int getSum(int A,int N){
    int i,temp,reminader = 0;
    int arr[MAX_N+1];
    for(i=0;i<N;i++){
        temp = A*(N-i) + reminader;
        
        arr[i] = temp%10;                     
        reminader = temp/10;
        cout<<temp<<"------"<<arr[i]<<"-----"<<reminader<<endl;
        system("pause");
    }
    
    if(remainder){
        arr[i] = remainder;
    }
    else
        i--;
    for(;i>=0;i--){
        cout<<arr[i];
    }
    
    return 0;
    
}


int main(){
    int A,N;
    //int Sum[MAX_N];
    cin>>A;
    cin>>N;
    if(N == 0){
  
        cout<<0<<endl;
        return 0;
    }
    A = getSum(A,N);
   
    //cout<<Sum<<endl;
    return 0;
}



2.4 递增的整数序列链表的插入


List Insert( List L, ElementType X ){
    List Now_L,temp,Point;  //point为要插入的点
    
    Point=(List)malloc(sizeof(struct Node));     //创建新节点要预约内存空间
    Point->Data = X;
    
    if (L->Next && L->Next->Data >= X){   //X要插在头结点后,且满足其后不为空。
        Point->Next = L->Next;
        L->Next = Point;
        return L;
    }
    temp = L;
    Now_L = L;
    
    while(Now_L->Next){
        if(Now_L->Data >= X){   //执行插入过程
            temp->Next = Point;
            Point->Next = Now_L;
            return L;
        }
        temp = Now_L;  //上一步的指针
        Now_L = Now_L->Next;
    }
    if(Now_L->Next == NULL){
        Now_L->Next = Point;
        Point->Next = NULL;
    }
    
    return L;
    
}

2.5 有序数组的归并

List Merge( List L1, List L2 ){
    
    List L,Head; 
    L = (List)malloc(sizeof(struct Node));
    Head = L;
    Head ->Next = NULL;

    List p1 = L1->Next,p2 = L2->Next;
    L1->Next = NULL; L2->Next = NULL;    //注意原程序中L1,L2会归为NUll;

    while((p1)&&(p2)){
        if(p1->Data > p2->Data){
            L->Next = p2;
            L = L->Next;
            p2 = p2->Next;
        }
        else {
            L->Next = p1;
            L = L->Next;
            p1 = p1->Next;
        }
    }
    if(p1)  L->Next = p1;//后面直接接上
    if(p2)  L->Next = p2;

    return Head;

    }
   

习题2.6 递归求简单交错幂级数的部分和
这题有很简单的解法,但是要动脑。我会把自己写的和最优解法都写出来。

//自己的
double fn( double x, int n ){
    if(n==1||n==0){
        return (n==1)? x:0;
    }
    double ans = -1;
    int i;
    for(i=0;i<n;i++){
        ans *= ((-1)*x);
    }
    n--;
    ans += fn(x,n);
    
    return ans;
}
//最优解法
//需要发现原式可以转换为x(1-x(1-x(1-x.....)))
double fn( double x, int n ){
    if(n==1){
        return x;
    }
    return x*(1-fn(x,n-1));
}

2.7 弹球距离 单纯的循环就行。

double dist( double h, double p ){
    
    double distance=h;
    while((h*=p) && (h>=TOL)){  //注意这里记得加括号,不然会出bug
        distance += 2*h;
    }
    
    return distance;
}

2.8 输出全排列

#include <iostream>
using namespace std;
//本题要了解一下深度优先搜索dfs
int visited[10];     //用来标记已经访问过的点
char s[15];        //用来输出字符串
int n;
void Full(int a){
    
    if(a>n){
        s[n+1] = '\0';    //终止符
        cout<<s+1<<endl;
        return; 
    }
    int i;
    for(i=1;i<=n;i++){
        if(!visited[i]){
            s[a]=(i)+'0';
            visited[i] = 1;
            Full(a+1);
            visited[i] = 0;
        }
    }
  
}


int main(){
    scanf("%d",&n);
    Full(1);
    return 0;
}

3.3 线性表的区间删除

List Delete( List L, ElementType minD, ElementType maxD ){
    
    Position Previous = 0,Now = 0;

    while(Now <= L->Last){
        if(!((L->Data[Now] > minD) && (L->Data[Now] < maxD))) //筛选留在表内的数据,从左到右依次按列表存放
        {
            L->Data[Previous] = L->Data[Now];
            Previous++;
        }
        Now++;
    }
    
    L->Last = Previous-1;    //前面++了,这里减回来,从而获得最后一个元素的地址
    
    
   return L;
    
    
}

3.4 最长连续递增子序列

#include <iostream>
using namespace std;
#define Max_N 100001
#define ElementType int
#define Position int

typedef struct LNode *List;
struct LNode{
    ElementType Data[Max_N];
    Position Last;
};   //注意定义结构体要加分号!!!!!!!!!!!!!!!!

List ReadList(List L,int number){
    int i;
    for(i=0;i<number;i++){
        cin>>L->Data[i];
    }
    L->Last = i-1;
    return L;
}

void FindMaxSequence(List L){
    //首先找到最大顺序起始点和终点,采用迭代的方法
    int Sum=0,temp=0;   //记录顺序子列和个数
    Position Max_Start =0;
    int i,j=0;
    for(i=0;i<=(L->Last);i++){
        if(L->Data[i] < L->Data[i+1]){
            temp++;
        }
        else{
            if(temp > Sum){
                Sum = temp;
                Max_Start = i - Sum;
            }
            temp =0;
        }      
    }
    //注意最后一位的时候,有可能超了Sum。
    if(temp > Sum){
        Sum++;
    }
    
    //打印
    for(i=0;i<Sum;i++){
        cout<<(L->Data[Max_Start+i])<<' ';
    }
    cout<<(L->Data[Max_Start+i])<<endl;
    
}




int main(){
    List L;
    int number;
    cin>>number;
    if(number > Max_N) return false;
    
    L = (List)malloc(sizeof(struct LNode));
    L = ReadList(L,number);
    FindMaxSequence(L);
    
    return 0;
    
}

3.5 求链表的倒数第m个元素
这一题我的方法时间复杂度为O(2n),我看别人的方法中还有更好的,***设置两个相差m的指针p1,p2;当p1指向终点时,p2所指就是要的值了,它的时间复杂度应该是O(n)***。比我的好

ElementType Find( List L, int m ){
    List Head;
    Head = L;
    int number=0,i=0,Cut,Value;
    while( (L->Next) && (L = L->Next)){
        number++;
        }
    if(m > number) {
        return ERROR;
    } 
    L = Head;
    Cut = number - m;
    while((L->Next) && (L = L->Next)){
        if(i==Cut) {
            Value = L->Data;
            L = Head;
            return Value;
        }
        i++;
    }
    return ERROR;
}

3.6 一元多项式的乘法与加法运算
目前还有点问题,只能做对一般情况,极端情况会出错。
刷满分的时候再改,留个坑在这里。`

#include <iostream>
using namespace std;

typedef struct PolyNode *PtrToPolyNode;
struct PolyNode{
    int Coe;
    int Index;
    PtrToPolyNode Next;
};
typedef PtrToPolyNode Polynomial;    //创建指针别名

Polynomial Attach(int num1){
    int i;
    Polynomial front,temp,Head;
    front = (Polynomial)malloc(num1 * sizeof(struct PolyNode));
    Head = front;
    for(i=0;i<num1;i++){
        temp = (Polynomial)malloc(num1 * sizeof(struct PolyNode));
		temp ->Next = 0;
        front->Next = temp;
        front = front->Next;
        cin>>temp->Coe;
        cin>>temp->Index;
    }
    front->Next = 0;
    return Head;
}

Polynomial NewNode(int Coe1,int Index1){
    Polynomial New;
    New = (Polynomial)malloc(sizeof(struct PolyNode));
    New->Coe = Coe1;
    New->Index = Index1;
	New->Next = 0;
    return New;
}



Polynomial Sum(Polynomial a1, Polynomial a2)
{
    Polynomial SumHead,Head;
    SumHead = (Polynomial)malloc(sizeof(struct PolyNode));
    Head = SumHead;      //记录头结点地址
    a1 = a1->Next;a2 = a2->Next;    //进入头结点后第一个元素
    while(a1&&a2){
        if (a1->Index > a2->Index){
            SumHead ->Next = NewNode(a1->Coe,a1->Index);
			SumHead = SumHead->Next;
            a1 = a1->Next;
        }
        else if(a1->Index == a2->Index){
            SumHead ->Next = NewNode((a1->Coe + a2->Coe),a1->Index);
			SumHead = SumHead->Next;
            a1 = a1->Next;
            a2 = a2->Next;    
        }
        else{
            SumHead ->Next =  NewNode(a2->Coe,a2->Index);
			SumHead = SumHead->Next;
            a2 = a2->Next;
        }
    }   //接下来加入剩余元素
    
    for(;a1;a1 = a1->Next){
		SumHead ->Next =  NewNode(a1->Coe,a1->Index);
		SumHead = SumHead->Next;
		}
    for(;a2;a2 = a2->Next){
		SumHead ->Next = NewNode(a2->Coe,a2->Index);
		SumHead = SumHead->Next;
		}
    
    return Head;
}

Polynomial Insert(Polynomial TimesHead,Polynomial Node){           //按照指数大小插入节点
    //首先判断如果是空链表,则直接插入
    Polynomial Head = TimesHead,temp;
	temp = TimesHead;
    if((TimesHead->Next == 0)&&(!temp->Coe)){           //空列表情况,下一个为空且当前系数为空
        TimesHead->Next = Node;
        return Head;
    }
	
    TimesHead = TimesHead->Next;
    while(TimesHead){
        if(Node->Index > TimesHead->Index){
            temp->Next = Node;
            Node->Next = TimesHead;
            return Head;
        }
		else if(Node->Index == TimesHead->Index){
			TimesHead->Coe = Node->Coe + TimesHead->Coe;
			return Head;
		}
        temp = TimesHead;
        TimesHead = TimesHead->Next;
    }
    temp->Next = Node;
    return Head;
    
}


Polynomial  Times(Polynomial a1,Polynomial a2){
    Polynomial TimesHead,Head,a1_Head,a2_Head,Node;
    TimesHead = (Polynomial)malloc(sizeof(struct PolyNode));
	TimesHead ->Coe = 0;
	TimesHead ->Index = 0;
	TimesHead ->Next = 0;
    Node = (Polynomial)malloc(sizeof(struct PolyNode));
    Head = TimesHead;
	a1_Head = a1;
	a2_Head = a2;
    a1 = a1->Next;a2 = a2->Next; //进入头结点后第一个元素
    while(a1){
        while(a2){
            Node = NewNode((a1->Coe * a2->Coe),(a1->Index + a2-> Index));
            TimesHead = Insert(TimesHead,Node);
            a2 = a2->Next;	
        }
        a1 = a1->Next;      //重置,a1进入Next,a2返回头部重新开始。
        a2 = a2_Head->Next;
    }
	
    return Head;
}


int main(){

    int num1,num2,i;
    Polynomial Array1_Head,Array2_Head,Head_Sum,Head_Mult;
    cin>>num1;
    Array1_Head = Attach(num1);
    cin>>num2;
    Array2_Head = Attach(num2);
	
    Head_Sum = Sum(Array1_Head,Array2_Head);
    Head_Sum = Head_Sum->Next;
    Head_Mult = Times(Array1_Head,Array2_Head);
    Head_Mult = Head_Mult->Next;
	
	while(Head_Mult->Next){
			cout<< Head_Mult->Coe << " "<<Head_Mult->Index<< " ";
			Head_Mult = Head_Mult->Next;			
		}
		cout<<Head_Mult->Coe << " "<<Head_Mult->Index<<endl;
		

    while(Head_Sum->Next){
        cout << Head_Sum->Coe<<" "<<Head_Sum->Index <<" ";
		Head_Sum = Head_Sum->Next;
	}
	cout << Head_Sum->Coe<<" "<<Head_Sum->Index <<endl;
	
    return 0;
}



  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值