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
。 对于任何数x
和0
,有x ^ 0 = x
。 XOR运算是可交换的,也就是说x ^ y = y ^ x
。
利用这些性质,我们可以在不需要临时变量的情况下交换两个变量a
和b
的值。下面演示如何操作:
a = a ^ b;
// 此步骤后,a 变成了两数的 XORb = a ^ b;
// 此步骤中,原来的 a(即 a ^ b)被 XOR 上现在的 b(原来的 b),所以 b 变成了原来的 aa = a ^ b;
// 此步骤中,原来的 a(即现在的 b)被 XOR 上现在的 a(原来的 a XOR 原来的 b),所以 a 变成了原来的 b
这样,a 和 b 的值就被交换了,而没有使用任何额外的存储变量。