原地算法实现数组反转

       原地算法是一种使用小的,固定数量的额外之空间来转换资料的算法。当算法执行时,输入的资料通常会被要输出的部分覆盖掉。原地算法保证不再额外的开辟内存空间的情况下,实现数据的转换,其空间复杂度为O(1)。

        原地算法常用的策略是使用双指针,比如将一个指针指向数组头部,一个指针指向数组尾部,头指针和尾指针相向而行,最终交汇,这种思路可以解决很多原地算法的问题。

        下面通过原地算法的思想,来实现一个数组的反转。

  一、定义双指针

typedef  unsigned int uint32 ;

typedef struct  TwoPointers
{
    /**左指针*/
   int left;

   /**右指针*/
   int right;

} Tptr;


/**
 * 数组反转
*/
void   reversal_arr(uint32* head,int  len);

/**
 * 展示数组
*/
void   show_arr(uint32* head,int  len);

二、函数实现

/**
 * 数组反转
*/
void   reversal_arr(uint32* head,int  len)
{
    show_arr(head,len);
    
    Tptr  tptr;
    Tptr* p = &tptr;
    p->left = 0;
    p->right = len-1;
     while (p->left < p->right)
     {
        uint32  temp = head[p->left];
        head[p->left] = head[p->right];
        head[p->right] = temp;
        p->left =  p->left +1 ;
        p->right = p->right -1;
     }
     show_arr(head,len);
}

/**
 * 展示数组
*/
void   show_arr(uint32* head,int  len)
{
    if(head == NULL){
        perror("arr  is not  init");
        exit(0);
    }
    printf("----------------\n");
    int  i = 0;
    for(i;i<len;i++)
    {
        printf("%d\t",head[i]);
    }
     printf("\n");
}

三、算法测试

    uint32 arr[] = { 99 , 88 , 77 , 66 , 55 , 44 , 33 ,22 ,11 };
    uint32* head =  &arr[0];
    int len =  sizeof(arr)/sizeof(uint32);
    reversal_arr(head,len);
   

      完美实现反转。 

### JavaScript 中的数组反转 在 JavaScript 中,可以通过内置方法 `reverse()` 来实现数组反转。此方法会直接修改原始数组,将其元素顺序颠倒[^1]。 ```javascript let array = [1, 2, 3, 4, 5]; array.reverse(); console.log(array); // 输出: [5, 4, 3, 2, 1] ``` 对于不希望改变原数组的情况,可以在调用 `reverse()` 方法前创建一个副本: ```javascript let originalArray = [1, 2, 3, 4, 5]; let reversedArray = [...originalArray].reverse(); console.log(originalArray); // 输出: [1, 2, 3, 4, 5] console.log(reversedArray); // 输出: [5, 4, 3, 2, 1] ``` --- ### 非递归方式的数组反转算法 通过双指针技术可以实现一种高效的原地数组反转算法。该算法的核心思想是从数组两头开始逐步交换元素直到相遇[^3]。这种方法适用于任何类型的数组(如整型或字符型),并且不会额外占用存储空间。 以下是基于 Java 的非递归实现示例: ```java public static void reverseArrayIterative(int[] arr) { int start = 0; int end = arr.length - 1; while (start < end) { // 交换 start 和 end 处的元素 int temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; // 移动指针 start++; end--; } } ``` 上述代码同样适用于字符数组或其他数据类型,只需调整参数类型即可。 --- ### 递归方式的数组反转算法 除了迭代版本外,还可以采用递归来完成同样的功能。递归函数每次处理一对元素并缩小范围直至条件满足[^2]。 下面是递归版的 Java 实现: ```java public static void reverseArrayRecursive(int[] arr, int start, int end) { if (start >= end) { return; } // 交换 start 和 end 处的元素 int temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; // 继续对剩余部分进行操作 reverseArrayRecursive(arr, start + 1, end - 1); } // 调用示例 int[] exampleArray = {1, 2, 3, 4, 5}; reverseArrayRecursive(exampleArray, 0, exampleArray.length - 1); System.out.println(Arrays.toString(exampleArray)); // 输出: [5, 4, 3, 2, 1] ``` --- ### 数组反转的理论基础 无论是使用内置方法还是手动编写逻辑,其核心都是将位于两端的元素互换位置。当数组长度为奇数时,中心元素无需变动;而对于偶数长度,则不存在单独的中心点[^4]。因此,在设计具体方案时需注意边界情况以及效率考量。 #### 时间复杂度分析 - **时间复杂度**: O(n),其中 n 表示数组大小。因为每一步只涉及常量级的操作,并且总共执行约 n/2 次。 - **空间复杂度**: 如果允许就地修改,则可达到 O(1);否则可能需要额外的空间来保存临时变量或者复制整个结构。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值