解决数组循环右移案例 !!!(C++)

目标

实现将顺序表(数组)中的结点循环右移 k 位的运算。要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。

解决方法

方案1---逆序法

#include <iostream>
using namespace std;
#define MAXSIZE 100
typedef struct {
    int *elem;
    int length;
}Array;//大家不用纠结用不用创建结构体,都可以
int arr[MAXSIZE] = {1,2,3,4,5,6,7};
void reverse(int start, int end);
int main() {
    int k;
    Array array;
    array.length = 7;
    array.elem = arr;
    cout << "input K:";
    cin >> k;
    k = k % array.length;//简单优化一下输入数据
    reverse(0, array.length - 1);//先全部逆序
    reverse(0, k - 1);           //逆序前半部分
    reverse(k, array.length - 1);//逆序后半部分(也可以最后进行全部逆序)
    for (int i = 0; i <= array.length - 1; i++) {
        cout << arr[i] << " ";
    }
    return 0;
}
//核心:
void reverse(int start, int end) {
    int num = (end - start + 1) / 2;//因为前后交换,所有循环一半
    for (int i = 1; i <= num; i++) {
        int tmp;
        tmp = arr[start];
        arr[start] = arr[end];
        arr[end] = tmp;
        end--;
        start++;
    }
}

例如:移动4位

原数组 123456

全部逆置 654321

前半部分逆置 + 后半部分逆置 345612

方案2---公式法

右移动K位后 该数据所在位置
核心公式 : 该数据下标 =(原位置下标 + K)% 数据总数
但需要创建一个新数组来存储移动后的所有数据
#include <iostream>
using namespace std;
#define MAXSIZE 100
typedef struct {
    int *elem;
    int length;
}Array;//大家不用纠结用不用创建结构体,都可以
int arr[MAXSIZE] = {1,2,3,4,5,6,7};
void reverse(int start, int end);
int main() {
    int k;
    int newarr[MAXSIZE] = {0};
    Array array;
    array.length = 7;
    array.elem = arr;
    cout << "input K:";
    cin >> k;
    k = k % array.length;//简单优化一下输入数据
    for (int i = 0; i <= array.length -1; i++) {
        newarr[(i + k) % array.length] = arr[i];
    }
    for (int i = 0; i <= array.length - 1; i++) {
        cout << newarr[i] << " ";
    }
    return 0;
}

方案3---自创的 哈哈哈哈

既然被迫新开辟数组,那我们也可以尝试另一种与公式法类似的方法。

我用新数组去 “扫描” 原数组,但不是头 “扫描”,而是从算出的应该是第一个数的下标开始 “扫描”。

例如:移动4位

从字符4 开始存入新数组。

我就不展示代码了,就是给出我一开始的想法。哈哈哈哈

解决方法还有,我就写出了我感觉不错的方案1和方案2。

如果有不准确的地方,欢迎大家指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值