数据结构代码集训day5【适合考研、自学、期末和专升本】

今日题目来自B站up:白话拆解数据结构


题目如下:

1、已知在一维数组A[m+n]中依次存放两个线性表(a1,a2,...,am)和(b1,b2,...,bn),编写一个函数,将数组中两个顺序表互换,即将(b1,b2,...,bn)放在(a1,a2,...,am)的前面。

2、【全国统考2010】设将n(n>1)个整数存放到一维数组R中。试设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0<p<n)个位置,即将R中的数组由(X0,X1, … Xn-1)变换为(Xp,Xp-1, … Xn-1,X0,X1, … Xp-1)。要求:

(1)给出算法的基本设计思想。

(2)根据设计思想,采用C、C++或JAVA语言描述算法,关键之处给出注释。

(3)说明你所涉及算法的时间复杂度和空间复杂度。


题一:

        感觉题目有点小瑕疵,如果是数组里存两个线性表,由于线性表的结构体有个length域,实际上是这么个情况:

        一是A[m+n]空间不够存,而是要跳开length来存比较麻烦。

        对题目进行小修改: 在线性表A中依次存放两个数组,其它不变。或者干脆就全改成数组也行。

        法一:申请一个临时数组B,大小是两个数组的长度之和;将表A的后n部分整体赋值给B数组的前面,再将表A的前m部分整体赋值给B数组的后面;最后将B数组的值再还给表A即可!

bool new_array(SqList &L,int m,int n){

    if(L.length==0) return false;

    int B[m+n];

    for(int i=m,j=0;i<L.length;i++,j++) //表的后n部分整体赋值给B数组的前面

        B[j] = L.data[i];

    for(int i=0,j=n;i<m;i++,j++)    // 表的前m部分整体赋值给B数组的后面

        B[j] = L.data[i];

   

    // 将B数组的值整体赋值给表

    for(int i=0,j=0;i<L.length;i++,j++)

        L.data[i]=B[j];

   

    return true;

}

        法二:这个不太好想。先将表A的前m部分逆置,再将表A的后n部分逆置,最后将表A整体逆置。

注意第二个循环的条件要加上m进行补足,因为i是从m开始的!

void swap_elem(SqList &L, int i, int j){  

    int tmp = L.data[i];

    L.data[i] = L.data[j];

    L.data[j] = tmp;

}

bool reverse_list(SqList &L,int m,int n){

    if(L.length==0) return false;       

    for(int i=0,j=m-1;i<m/2;i++,j--)        // 前m部分逆置

        swap_elem(L,i,j);

    for(int i=m,j=L.length-1;i<m+n/2;i++,j--)        // 后n部分逆置

        swap_elem(L,i,j);

    for(int i=0,j=L.length-1;i<L.length/2;i++,j--)        // 整体逆置

        swap_elem(L,i,j);

    return true;

}

 看看结果把:m=3,n=7

再来试试m=6,n=4

over!完整代码如下:(在vscode环境下已成功跑通)

#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std;

// 一维数组A[m+n]中存了俩表a[m]和b[n]。要求编写一个函数将这两个顺序表位置互换

struct SqList{
    int data[100];
    int length;
};

// 法一:申请一个临时数组
bool new_array(SqList &L,int m,int n){
    if(L.length==0) return false;
    int B[m+n];
    for(int i=m,j=0;i<L.length;i++,j++) //表的后n部分整体赋值给B数组的前面
        B[j] = L.data[i];
    for(int i=0,j=n;i<m;i++,j++)    // 表的前m部分整体赋值给B数组的后面
        B[j] = L.data[i];
    
    // 将B数组的值整体赋值给表
    for(int i=0,j=0;i<L.length;i++,j++)
        L.data[i]=B[j];
    
    return true;
}
// 法二:先将a数组逆置,再将b数组逆置,最后整体逆置
void swap_elem(SqList &L, int i, int j){  
    int tmp = L.data[i];
    L.data[i] = L.data[j];
    L.data[j] = tmp;
}

bool reverse_list(SqList &L,int m,int n){
    if(L.length==0) return false;
    for(int i=0,j=m-1;i<m/2;i++,j--)
        swap_elem(L,i,j);
    for(int i=m,j=L.length-1;i<m+n/2;i++,j--)
        swap_elem(L,i,j);
    for(int i=0,j=L.length-1;i<L.length/2;i++,j--)
        swap_elem(L,i,j);
    return true;
}

int main() {
    SqList L;
    L.length =10;
    srand(static_cast<unsigned int>(time(nullptr)));
    // 随机赋值
    for(int i =0;i<L.length;i++){
        L.data[i] = rand()%10;   
    }
    cout << "Original list: ";
    for (int i = 0; i < L.length; i++) {
        cout << L.data[i] << " ";
    }
    cout << endl;

    if (reverse_list(L, 6,4)) {
        cout << "The new list is: ";
        for (int i = 0; i < L.length; i++) {
            cout << L.data[i] << " ";
        }
        cout << endl;
    } else {
        cout << "The list is empty." << endl;
    }

    return 0;
}

题二:这题和题一几乎一致

        法一:新建个临时数组,前p个元素放到数组后面,后n-p个元素放到数组前面

bool zuoyi(int R[],int p,int n){

    int m[n];

    for(int i=p,j=0;i<n;i++,j++)

        m[j]=R[i];

    for(int i=0,j=n-p;i<p;i++,j++)

        m[j]=R[i];

    for(int i=0,j=0;i<n;i++,j++)

        R[i]=m[j];

    return true;

}

        时间复杂度为O(n),空间复杂度为O(n)

法二: 和上题一样逆置的思想,前p个逆置,后n-p个逆置,再整体逆置。因为其实就是前p个数组和后n-p个数组调换位置而已!

void swap_elem(int a[], int i, int j){  

    int tmp = a[i];

    a[i] = a[j];

    a[j] = tmp;

}

bool reverse_list(int a[],int p,int n){

    for(int i=0,j=p-1;i<p/2;i++,j--)

        swap_elem(a,i,j);

    for(int i=p,j=n-1;i<p+(n-p+1)/2;i++,j--)        // 注意这里的判断条件

        swap_elem(a,i,j);

    for(int i=0,j=n-1;i<n/2;i++,j--)

        swap_elem(a,i,j);

    return true;

}

        时间复杂度为O(n/2),空间复杂度O(1)。高效 

试试结果:p=3,n=10(这里的n是数组长度)

p=6,n=10

over!完整代码如下:

#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std;

// 将n个整数存放到一维数组R中,设计一个尽可能高效的算法,将R中保存的序列循环左移P(0<p<n)个位置


// 法一:新建个临时数组,前p个元素放到数组后面,后n-p个元素放到数组前面
bool zuoyi(int R[],int p,int n){
    int m[n];
    for(int i=p,j=0;i<n;i++,j++)
        m[j]=R[i];
    for(int i=0,j=n-p;i<p;i++,j++)
        m[j]=R[i];
    for(int i=0,j=0;i<n;i++,j++)
        R[i]=m[j];
    return true;
}

// 法二:和题一一样逆置的思想,前p个逆置,后n-p个逆置,再整体逆置
void swap_elem(int a[], int i, int j){  
    int tmp = a[i];
    a[i] = a[j];
    a[j] = tmp;
}

bool reverse_list(int a[],int p,int n){
    for(int i=0,j=p-1;i<p/2;i++,j--)
        swap_elem(a,i,j);
    for(int i=p,j=n-1;i<p+(n-p+1)/2;i++,j--)
        swap_elem(a,i,j);
    for(int i=0,j=n-1;i<n/2;i++,j--)
        swap_elem(a,i,j);
    return true;
}

int main() {
    int a[10];
    srand(static_cast<unsigned int>(time(nullptr)));
    // 随机赋值
    for(int i =0;i<10;i++){
        a[i] = rand()%10;   
    }
    cout << "Original array: ";
    for (int i = 0; i < 10; i++) {
        cout << a[i] << " ";
    }
    cout << endl;

    if (reverse_list(a, 6,10)) {
        cout << "The new arry is: ";
        for (int i = 0; i < 10; i++) {
            cout << a[i] << " ";
        }
        cout << endl;
    } else {
        cout << "The list is empty." << endl;
    }

    return 0;
}

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值