2.6 线性表的逆置

逆置: 将表中的元素调整成与原来相反的顺序.

1. 顺序表的逆置

图1. 顺序表的逆置

用temp存储要交换的元素, temp = arr[ i ]; arr[ i ] = arr[ j ]; arr[ j ] = temp; 然后i++, j--. 若数组长度为偶数, 则i > j时结束循环; 若数组长度为奇数, 则i >= j时结束循环. 也即不管数组的长度是奇数还是偶数, 均为i < j时执行循环, 否则跳出循环.

cpp 复制代码
#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: 顺序表的逆置

cpp 复制代码
//数组逆置核心代码
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指向的结点的后面, 即可完成逆置操作.

cpp 复制代码
#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: 链表的逆置

cpp 复制代码
//链表逆置核心代码
while (p->next != q) 
{
    LNode* t = p->next;
    p->next = t->next;
    t->next = q->next;
    q->next = t;
}

代码4: 链表的逆置核心代码

相关推荐
颜酱2 小时前
二叉树分解问题思路解题模式
javascript·后端·算法
qianpeng8973 小时前
水声匹配场定位原理及实验
算法
董董灿是个攻城狮15 小时前
AI视觉连载8:传统 CV 之边缘检测
算法
AI软著研究员1 天前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish1 天前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
颜酱1 天前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
地平线开发者2 天前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶
董董灿是个攻城狮2 天前
大模型连载2:初步认识 tokenizer 的过程
算法
地平线开发者2 天前
地平线 VP 接口工程实践(一):hbVPRoiResize 接口功能、使用约束与典型问题总结
算法·自动驾驶
罗西的思考2 天前
AI Agent框架探秘:拆解 OpenHands(10)--- Runtime
人工智能·算法·机器学习