数据结构中常见的逆置问题【C/C++】

目录

  • 前言
  • 1 对于数字的逆置
    • 1.1 逆序输出数字的思路
    • 1.2 代码如下
    • 1.3 测试结果
  • 2 对于字符串的逆序输出
    • 2.1 逆序输出字符串的思路
    • 2.2 单行字符串保存在char类型数组中的具体代码
      • 2.2.1 单行字符串测试结果
    • 2.3 字符串为多行具体代码
      • 2.3.1 多行字符串测试结果
    • 2.4 String类型的字符串逆置的具体代码
      • 2.4.1 String字符串测试结果
  • 3 对于顺序表的逆置
    • 3.1 顺序表逆置的具体代码
    • 3.2 顺序表逆置测试结果
  • 4 对于链表的逆置
    • 4.1 链表就地逆置的具体代码
    • 4.2 链表就地逆置测试结果
  • 结语


前言

在复习数据结构与算法时,经常遇到逆置问题,无论是对数字的逆置还是对字符串乃至顺序表链表的逆置问题,对于我这个榆木脑袋来说都得思考半天。在此记录下自己思考的过程,在脑海里打下深深的印象!


1 对于数字的逆置

1.1 逆序输出数字的思路

设要逆置的数字为num,可以每次对num对10取余,余出的数字即为个位,再将num除以10消去个位,每次依次输出,则可以得到逆序输出到每一位的数字。在循环中将每一位乘十即可得到逆序输出的数字。

1.2 代码如下

void ReverseNum() {
	unsigned long num = 0;
	unsigned long result = 0;
	int a = 0;
	printf("输入要逆置的数字\n");
	scanf("%u", &num);

	unsigned long tmp = num;
	while (tmp > 0) {
		a = tmp % 10;
		tmp = tmp / 10;
		result = result * 10 + a;
	}
	printf("逆置后的数字为:%u\n", result);
}

1.3 测试结果

数据结构中常见的逆置问题【C/C++】_第1张图片

注意:这里采用无符号长整型输入输出,范围为0~(2^32-1)<32位> 或 0~(2^64-1)<64位>, 并且输入输出要用%u。

这里再复习一下各个字符的长度。
64位编译器
char :1个字节
char*(即指针变量): 8个字节(64位的寻址空间是2^64, 即64个bit,也就是8个字节。)
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
long long: 8个字节
unsigned long: 8个字节

32位编译器
char :1个字节
char*(即指针变量): 4个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节

浮点型变量
float:
1bit(符号位) 8bits(指数位) 23bits(尾数位)
double:
1bit(符号位) 11bits(指数位) 52bits(尾数位)


2 对于字符串的逆序输出

2.1 逆序输出字符串的思路

如果单行字符串是保存在char类型的数组中,那么可以采用对数组前后进行交换即可。
如果是多行元素对于可以采用一个二维数组来存储,用n保存行数,用scanf输入并用getchar来消掉回车。用gets_s()来读取缓冲区。
如果是string类型的字符串则可以采用反向迭代器。

2.2 单行字符串保存在char类型数组中的具体代码

感谢@天気がいい的指正!

//逆置字符串保存在char类型数组中的具体代码
void ReverseCharArray() {
	char arr[100] = { 0 };
	gets_s(arr);

	int len = strlen(arr);
	int low = 0;
	int high = len - 1;
	while (low < high) {
		char tmp = 0;
		tmp = arr[low];
		arr[low] = arr[high];
		arr[high] = arr[low];
		low++;
		high--;
	}
	printf("%s\n", arr);
}

2.2.1 单行字符串测试结果

在这里插入图片描述
在c语言中可以用gets_s(arr)或scanf(“%[^\n]”,arr)来跳过空格

2.3 字符串为多行具体代码

void ReverseMultiString() {
	printf("输入多行的行数\n");
	int n = 0;
	scanf("%d", &n);
	getchar();
	char** a = (char**)calloc(sizeof(char*), n);
	char tmp[50] = { 0 };
	printf("请输入字符串\n");
	for (int i = 0; i < n; i++) {
		a[i] = (char*)calloc(sizeof(char), 50);
		gets_s(tmp);
		int len = strlen(tmp);
		for (int j = 0; j < len; j++) {
			a[i][len - j - 1] = tmp[j];
		}
	}
	printf("逆置后字符串为\n");
	for (int i = 0; i < n; i++) {
		printf("%s\n", a[i]);
	}

	//二维数组的释放
	for (int i = 0; i < n; i++) {
		if (a[i] != NULL) {
			free(a[i]);
			a[i] = NULL;
		}
	}
	if (a != NULL) {
		free(a);
		a = NULL;
	}
}

2.3.1 多行字符串测试结果

多行字符串也能应用于单行字符串
数据结构中常见的逆置问题【C/C++】_第2张图片
测试多行字符串
数据结构中常见的逆置问题【C/C++】_第3张图片

三个注意的点:
1.因为对行数n的输入采用scanf,并用回车确定,因此缓冲区中会多出一个回车,要用getchar()读走。
2.注意对缓冲数组arr的大小的设置,如果太小会报错。
3.注意二维数组的释放要从内部开始,即一级指针a[i]开始,再到外层的二级指针a。

2.4 String类型的字符串逆置的具体代码

在C++中对String容器有反向迭代器,因此就极为方便。
这里的代码也采用C++的输入输出流。

void ReverseContainerString(){
	string str;
	getline(cin,str);
	string s(str.rbegin(), str.rend());
	cout << s << endl;
	return;
}

2.4.1 String字符串测试结果

在这里插入图片描述


3 对于顺序表的逆置

对于顺序表的逆置则与对数组逆置类似。
这里采用的顺序表是耿国华老师的顺序表结构

typedef struct SEQLIST {
	ElemType data[MAX];
	int last;//最后一个元素的下标,初始值为-1;
}SeqList;

3.1 顺序表逆置的具体代码

void ReverseSeqList(SeqList* L) {
	int low = 0;
	int high = L->last;
	while (low < high) {
		int tmp = 0;
		tmp = L->data[low];
		L->data[low] = L->data[high];
		L->data[high] = tmp;
		low++;
		high--;
	}
}

3.2 顺序表逆置测试结果

在这里插入图片描述


4 对于链表的逆置

这里采用的链表是耿国华老师的链表结构

typedef struct LINKNODE {
	ElemType data;
	struct LINKNODE* next;
}LinkNode, * LinkList;

4.1 链表就地逆置的具体代码

void ReverseLinkList(LinkList L) {
	if (L == NULL) {
		return;
	}
	LinkNode* p = L->next;
	L->next = NULL;
	while (p != NULL) {
		LinkNode* q = p->next;
		p->next = L->next;
		L->next = p;
		p = q;
	}
}

4.2 链表就地逆置测试结果

数据结构中常见的逆置问题【C/C++】_第4张图片


结语

现在就能想到这么多逆置了,如果有别的方法以后再补充,谢谢大家!

你可能感兴趣的:(数据结构,链表,算法)