逆置: 将表中的元素调整成与原来相反的顺序.
1. 顺序表的逆置
图1. 顺序表的逆置
用temp存储要交换的元素, temp = arr[ i ]; arr[ i ] = arr[ j ]; arr[ j ] = temp; 然后i++, j--. 若数组长度为偶数, 则i > j时结束循环; 若数组长度为奇数, 则i >= j时结束循环. 也即不管数组的长度是奇数还是偶数, 均为i < j时执行循环, 否则跳出循环.
#include <iostream>
/// <summary>
/// 数组最大长度
/// </summary>
const int MAX_SIZE = 10;
/// <summary>
/// 初始化数组
/// </summary>
/// <param name="arr">数组</param>
/// <param name="length">数组长度</param>
/// <returns></returns>
int initArr(int* arr, int length) {
if (length > MAX_SIZE || length <= 0) {
return 0;
}
for (int i = 0; i < length; i++)
{
arr[i] = i;
}
return 1;
}
/// <summary>
/// 数组逆置
/// </summary>
/// <param name="arr">数组</param>
/// <param name="length">数组长度</param>
/// <param name="left">逆置起始元素下标</param>
/// <param name="right">逆置终止元素下标</param>
/// <returns></returns>
int inversionArr(int* arr, int length, int left, int right) {
if (length > MAX_SIZE || length <= 0) { //length越界
return 0;
}
if (left < 0 || left > length - 1) { //起始元素下标越界
return 0;
}
if (right < 0 || right > length - 1) { //终止元素下标越界
return 0;
}
if (left > right) {
return 0;
}
//数组逆置核心代码
for (int i = left, j = right; i < j; i++, j--)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
return 1;
}
/// <summary>
/// 输出数组元素
/// </summary>
/// <param name="arr"></param>
/// <param name="length"></param>
void printArr(int* arr, int length) {
for (int i = 0; i < length; i++)
{
printf("%d\n", arr[i]);
}
}
int main()
{
int arr[MAX_SIZE]; //这里[]里面的值必须是常量
int length = 6;
int result = initArr(arr, length);
if (result == 1) {
printf("逆置前的数组元素:\n");
printArr(arr, length);
int result2 = inversionArr(arr, length, 3, 3);
if (result2 == 1) {
printf("逆置后的数组元素:\n");
printArr(arr, length);
}
}
}
代码1: 顺序表的逆置
//数组逆置核心代码
for (int i = left, j = right; i < j; i++, j--)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
代码2: 顺序表的逆置核心代码
2. 链表的逆置
图2. 链表的逆置
p指向逆置起始结点的前一个结点, q指向逆置终止结点, t 指向本次循环要逆置的结点. 每次循环时, 将p后面的结点从链表中取出, 放入q指向的结点的后面, 即可完成逆置操作.
#include <iostream>
/// <summary>
/// 链表结点结构体定义
/// </summary>
typedef struct LNode {
int data;
struct LNode* next;
}LNode;
/// <summary>
/// 链表逆置
/// </summary>
/// <param name="p"></param>
/// <param name="q"></param>
void inversionLinkList(LNode* p, LNode* q) {
if (p == q) {
return;
}
//链表逆置核心代码
while (p->next != q) {
LNode* t = p->next;
p->next = t->next;
t->next = q->next;
q->next = t;
}
}
/// <summary>
/// 输出链表的值
/// </summary>
/// <param name="H"></param>
void printLinkList(LNode* H) {
LNode* p = H;
while (p != NULL)
{
if (p->data != 0) {
printf("%d\n", p->data);
}
p = p->next;
}
}
int main()
{
LNode* H = (LNode*)malloc(sizeof(LNode));
LNode* A = (LNode*)malloc(sizeof(LNode));
LNode* B = (LNode*)malloc(sizeof(LNode));
LNode* C = (LNode*)malloc(sizeof(LNode));
LNode* D = (LNode*)malloc(sizeof(LNode));
H->data = NULL;
A->data = 1;
B->data = 2;
C->data = 3;
D->data = 4;
H->next = A;
A->next = B;
B->next = C;
C->next = D;
D->next = NULL;
printf("逆置前的链表: \n");
printLinkList(H);
inversionLinkList(A, A);
printf("逆置后的链表: \n");
printLinkList(H);
}
代码3: 链表的逆置
//链表逆置核心代码
while (p->next != q)
{
LNode* t = p->next;
p->next = t->next;
t->next = q->next;
q->next = t;
}
代码4: 链表的逆置核心代码