顺序表的就地倒置(C语言)

本文介绍了五种不同的方法来反转顺序列表(数组)中的元素,包括使用中间变量、递归、额外数组、栈以及XOR交换,同时讨论了它们的优缺点和适用场景,特别关注了空间复杂度和避免栈溢出问题。
摘要由CSDN通过智能技术生成

5种方法实现

#include  <stdio.h>
#include  <stdlib.h>

 #define MAXSIZE 100
 typedef int datatype;
 typedef struct{
   datatype a[MAXSIZE];
   int size;
 }sequence_list;

1.使用中间变量

void reverse(sequence_list *L)
{
    int left = 0, temp;
    int right = L->size - 1; // right指向最后一个元素的索引
    while (left < right) {
        temp = L->a[left];
        L->a[left] = L->a[right];
        L->a[right] = temp;
        left++;
        right--;
    }
}


 

2.递归

递归方法是一种优雅的解决方案,但由于顺序表(数组)通常在栈空间中操作,这种方法可能不太适用于大型数据集,因为可能会导致栈溢出。

void reverseUtil(sequence_list *L, int start, int end) {
    if (start >= end) return;

    int temp = L->a[start];
    L->a[start] = L->a[end];
    L->a[end] = temp;

    reverseUtil(L, start + 1, end - 1);
}

void reverse(sequence_list *L) {
    reverseUtil(L, 0, L->size - 1);
}


3. 使用额外的数组

创建一个新数组并复制元素,在新数组中以相反的顺序填充原数组。这种方法空间复杂度较高,但代码易于理解。

void reverse(sequence_list *L) {
    int *b = (int *)malloc(L->size * sizeof(int));
    int i, j;

    for (i = 0, j = L->size - 1; i < L->size; i++, j--) {
        b[j] = L->a[i];
    }

    for (i = 0; i < L->size; i++) {
        L->a[i] = b[i];
    }
    
    free(b);
}

4.使用栈

用一个栈来反转顺序表中的元素。将所有元素压栈,然后再弹出到顺序表中。

void reverse(sequence_list *L) {
    int stack[L->size];
    int i, top = 0;

    // 将元素压入栈
    for (i = 0; i < L->size; i++) {
        stack[top++] = L->a[i];
    }

    // 从栈中弹出元素到顺序表
    for (i = 0; i < L->size; i++) {
        L->a[i] = stack[--top];
    }
}

5.XOR 交换

使用 XOR 运算符交换两个元素,这样就不需要使用额外的临时变量。在实际编程中,由于XOR交换可能会导致可读性降低,且如果用于交换相同位置的值会导致错误(因为结果将为0),所以通常不推荐使用这种方法。

void reverse(sequence_list *L) {
    int left = 0;
    int right = L->size - 1;

    while (left < right) {
        L->a[left] ^= L->a[right];
        L->a[right] ^= L->a[left];
        L->a[left] ^= L->a[right];

        left++;
        right--;
    }
}

XOR交换是一种不需要使用额外变量来交换两个变量值的技巧。这种技巧利用了XOR运算的以下性质:

对于任何数x,有x ^ x = 0。 对于任何数x0,有x ^ 0 = x。 XOR运算是可交换的,也就是说x ^ y = y ^ x

利用这些性质,我们可以在不需要临时变量的情况下交换两个变量ab的值。下面演示如何操作:

  1. a = a ^ b; // 此步骤后,a 变成了两数的 XOR
  2. b = a ^ b; // 此步骤中,原来的 a(即 a ^ b)被 XOR 上现在的 b(原来的 b),所以 b 变成了原来的 a
  3. a = a ^ b; // 此步骤中,原来的 a(即现在的 b)被 XOR 上现在的 a(原来的 a XOR 原来的 b),所以 a 变成了原来的 b

这样,a 和 b 的值就被交换了,而没有使用任何额外的存储变量。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值