2021-09-20

数据结构-王道-习题-顺序表(1-8)

1、从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删除的元素的值。空出的位置由最后的一个元素填补,若顺序表为空,则显示错误信息并退出运行。

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct SQList {
	int * pData;
	int length=0;
	int Maxsize=10 ;
}SqList,*pSqList;
bool DelMinElement(pSqList pL, int *val);
void Traverse(pSqList pL);
void InitSqlist(pSqList pL);
int main(void){
	SqList L;
	int val;
	InitSqlist(&L);
	Traverse(&L);
	if (DelMinElement(&L, &val)) {
		printf_s("最小元素:%d  已删除!\n",val);
	}
	Traverse(&L);
	return 0;
}
void InitSqlist(pSqList pL) {
	pL->pData = (int*)malloc(sizeof(int)*pL->Maxsize);
	int a[5] = { 3,5,9,1,10 };
	for (int i = 0; i < 5; i++) {
		pL->pData[i] = a[i];
		pL->length++;
	}
	return;
}
void Traverse(pSqList pL) {
	int i;
	if (pL->length == 0) {
		exit(-1);
	}
	for (i = 0; i < pL->length; i++) {
		printf_s("%d	", pL->pData[i]);
	}
	printf_s("\n");
}
bool DelMinElement(pSqList pL, int *val) {
	if (pL->length == 0){
		printf_s("顺序表为空!\n");
		return false;
}
	int pos=0;//标记最小元素的位置
	int i;
	*val = pL->pData[0];
	for (i = 1; i < pL->length; i++) {
		if (*val > pL->pData[i]) {
			*val = pL->pData[i];
			pos = i;
		}
	}
	pL->pData[pos] = pL->pData[pL->length - 1];
	pL->length--;
	return true;
}

运行结果:
在这里插入图片描述

2、设计一个高效的算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)。

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct SQList {
	int * pData;
	int length = 0;
	int Maxsize = 10;
}SqList, *pSqList;
void Traverse(pSqList pL);
void InitSqlist(pSqList pL);
void Inversion(pSqList pL);
int main(void) {
	SqList L;
	InitSqlist(&L);
	Traverse(&L);
	printf_s("倒置\n");
	Inversion(&L);
	Traverse(&L);
	return 0;
}
void InitSqlist(pSqList pL) {//初始化
	pL->pData = (int*)malloc(sizeof(int)*pL->Maxsize);
	int a[7] = { 3,5,9,1,10,8,11 };
	for (int i = 0; i < 7; i++) {
		pL->pData[i] = a[i];
		pL->length++;
	}
	return;
}
void Traverse(pSqList pL) {//遍历
	int i;
	if (pL->length == 0) {
		exit(-1);
	}
	for (i = 0; i < pL->length; i++) {
		printf_s("%d	", pL->pData[i]);
	}
	printf_s("\n");
}
void Inversion(pSqList pL) {//倒置
	int i = 0;
	int j = pL->length -1;
	for (i, j; i < j; i++, j--) {
		int t;
		t = pL->pData[i];
		pL->pData[i] = pL->pData[j];
		pL->pData[j] = t;
	}
	return;
}

运行结果:
在这里插入图片描述

3、对长度为n的顺序表l编写一个时间复杂度为o(n),空间复杂度为o(1) 的算法,该算法删除线性表中所有值为x的数据元素。

方法一、用k记录所有等于x的数据元素个数

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct sqlist {
	int * pdata;
	int length = 0;
	int maxsize = 15;
}sqlist, *psqlist;
void traverse(psqlist pl);//遍历
void initsqlist(psqlist pl);//初始化
void delvalofx(psqlist pl, int x);//删除
int main(void) {
	sqlist l;
	initsqlist(&l);
	traverse(&l);
	delvalofx(&l, 3);
	traverse(&l);
	return 0;
}
void initsqlist(psqlist pl) {//初始化
	pl->pdata = (int*)malloc(sizeof(int)*pl->maxsize);
	int a[10] = { 1,7,3,5,9,3,10,3,11 ,3};
	for (int i = 0; i < 10; i++) {
		pl->pdata[i] = a[i];
		pl->length++;
	}
	return;
}
void traverse(psqlist pl) {//遍历
	int i;
	if (pl->length == 0) {
		exit(-1);
	}
	for (i = 0; i < pl->length; i++) {
		printf_s("%d	", pl->pdata[i]);
	}
	printf_s("\n");
}
void delvalofx(psqlist pl, int x) {
	if (pl->length == 0)
		exit(-1);
	int k = 0;//用于记录所有等于x的数据元素个数
	int i = 0;
	while (i < pl->length) {
		if (pl->pdata[i] == x) {
			k++;
		}
		else {
			pl->pdata[i - k] = pl->pdata[i];
		}
		i++;
	}
	pl->length = pl->length - k;
	return;
}

方法二、用k记录所有不等于x的数据元素个数

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct SQList {
	int * pData;
	int length = 0;
	int Maxsize = 15;
}SqList, *pSqList;
void Traverse(pSqList pL);//遍历
void InitSqlist(pSqList pL);//初始化
void DelValOfx2(pSqList pL, int x);//删除
int main(void) {
	SqList L;
	InitSqlist(&L);
	Traverse(&L);
	DelValOfx2(&L, 3);
	Traverse(&L);
	return 0;
}
void InitSqlist(pSqList pL) {//初始化
	pL->pData = (int*)malloc(sizeof(int)*pL->Maxsize);
	int a[10] = { 1,7,3,5,9,3,10,3,11 ,3 };
	for (int i = 0; i < 10; i++) {
		pL->pData[i] = a[i];
		pL->length++;
	}
	return;
}
void Traverse(pSqList pL) {//遍历
	int i;
	if (pL->length == 0) {
		exit(-1);
	}
	for (i = 0; i < pL->length; i++) {
		printf_s("%d	", pL->pData[i]);
	}
	printf_s("\n");
}
void DelValOfx2(pSqList pL, int x) {
	if (pL->length == 0)
		exit(-1);
	int k = 0;//用于记录所有不等于x的数据元素个数
	int i = 0;
	for (i; i < pL->length; i++) {
		if (pL->pData[i] != x) {
			pL->pData[k] = pL->pData[i];
			k++;
		}
	}
	pL->length = k;
	return;
}

运行结果:
在这里插入图片描述

4、从有序顺序表中删除其值在给定值s和t之间(s<t)的所有元素,若s或t不合理或顺序表为空,则显示错误信息并退出运行。

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct SQList {
	int * pData;
	int length = 0;
	int Maxsize = 15;
}SqList, *pSqList;
void Traverse(pSqList pL);//遍历
void InitSqlist(pSqList pL);//初始化
void DelBetwST(pSqList pL, int s,int t);//删除3-7之间数据
int main(void) {
	SqList L;
	InitSqlist(&L);
	Traverse(&L);
	DelBetwST(&L, 3,7);
	Traverse(&L);
	return 0;
}
void InitSqlist(pSqList pL) {//初始化
	pL->pData = (int*)malloc(sizeof(int)*pL->Maxsize);
	int a[10] = { 1,3,3,4,4,5,6,7,8 ,9 };
	for (int i = 0; i < 10; i++) {
		pL->pData[i] = a[i];
		pL->length++;
	}
	return;
}
void Traverse(pSqList pL) {//遍历
	int i;
	if (pL->length == 0) {
		exit(-1);
	}
	for (i = 0; i < pL->length; i++) {
		printf_s("%d	", pL->pData[i]);
	}
	printf_s("\n");
}
void DelBetwST(pSqList pL, int s, int t) {
	if (s >= t ) {
		printf_s("s或t值不合理\n");
		exit(-1);
	}
	if (pL->length == 0) {
		printf_s("顺序表为空\n");
		exit(-1);
	}
	int i = 0, j = 0;
	for (i; pL->pData[i] < s; i++);//用于定位到第一个大于等于s的位置
	if (i > pL->length) {
		printf_s("表中无此区间的数据存在\n");
		exit(-1);
	}
	for (j; pL->pData[j] < t; j++);//用于定位到第一个大于等于t的位置
	for (i, j; j < pL->length; i++, j++) 
		pL->pData[i] = pL->pData[j];
	pL->length = i;
	return;
}

运行结果:
在这里插入图片描述

5、从顺序表中删除其值在给定值S和t之间(包括s和t,s<t)的所有元素,若s或t不合理或顺序表为空,则显示出错误信息并退出运行。

#include <stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct SQLIST {
	int * pdata;
	int length = 0;//有效数据长度
	int Maxsize = 20;//申请空间(最大长度)
}SqList,*pSqList;
void InitSqList(pSqList pL);//初始化
void Traverse(pSqList pL);//遍历
void DelBetwst(pSqList pL,int s,int t);//删除
int main(void) {
	SqList L;
	InitSqList(&L);
	Traverse(&L);
	DelBetwst(&L,4,9);
	printf_s("删除4到9之间的所有元素!\n");
	Traverse(&L);
	return 0;
}
void InitSqList(pSqList pL) {
	pL->pdata = (int *)malloc(sizeof(int)*pL->Maxsize);
	if (pL->pdata == NULL) {
		printf_s("动态分配空间失败!\n");
		exit(-1);
	}
	int a[15] = { 3,5,2,9,3,4,10,6,8,11,4,9,13,15,1 };
	for (int i = 0; i < sizeof(a) / sizeof(int); i++) {
		pL->pdata[i] = a[i];
		pL->length++;
	}
}
void Traverse(pSqList pL) {
	int i = 0;
	if (pL->length == 0) {
		printf_s("表为空!\n");
		exit(-1);
	}
	for(i;i<pL->length;i++){
		printf_s("%d	", pL->pdata[i]);
	}
	printf_s("\n");
	return;
}
void DelBetwst(pSqList pL,int s,int t) {
	int k = 0;//记录在范围内的元素的个数
	if (s >= t) {
		printf_s("s或t输入不合法!\n");
		exit(-1);
	}
	if (pL->length == 0) {
		printf_s("表为空!\n");
		exit(-1);
	}
	for (int i = 0; i < pL->length; i++) {
		if (pL->pdata[i] >= s && pL->pdata[i] <= t)
			k++;
		else
			pL->pdata[i - k] = pL->pdata[i];
	}
	pL->length = pL->length - k;
}

运行结果:
在这里插入图片描述

6、从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不相同。

#include <stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct SQLIST {
	int * pdata;
	int length = 0;//有效数据长度
	int Maxsize = 20;//申请空间(最大长度)
}SqList, *pSqList;
void InitSqList(pSqList pL);//初始化
void Traverse(pSqList pL);//遍历
void DelTheSames(pSqList pL);//删除
int main(void) {
	SqList L;
	InitSqList(&L);
	Traverse(&L);
	DelTheSames(&L);
	printf_s("去重!\n");
	Traverse(&L);
	return 0;
}
void InitSqList(pSqList pL) {
	pL->pdata = (int *)malloc(sizeof(int)*pL->Maxsize);
	if (pL->pdata == NULL) {
		printf_s("动态分配空间失败!\n");
		exit(-1);
	}
	int a[10] = { 3,5,7,7,7,8,9,9,9,11 };
	for (int i = 0; i < sizeof(a) / sizeof(int); i++) {
		pL->pdata[i] = a[i];
		pL->length++;
	}
}
void Traverse(pSqList pL) {
	int i = 0;
	if (pL->length == 0) {
		printf_s("表为空!\n");
		exit(-1);
	}
	for (i; i < pL->length; i++) {
		printf_s("%d	", pL->pdata[i]);
	}
	printf_s("\n");
	return;
}
void DelTheSames(pSqList pL) {
	int i, j;
	if (pL->length == 0) {
		printf_s("表为空!\n");
		exit(-1);
	}
	for ( i = 0, j = 1; j < pL->length; j++) {
		if (pL->pdata[i] != pL->pdata[j]) {//有序的顺序表,相同值一定相邻
			i++;   //第一个元素即pL->pdata[0]一定存在
			pL->pdata[i] = pL->pdata[j];
		}
	}
	pL->length = i + 1;
	return;
}

运行结果:
在这里插入图片描述

7、将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表

#include <stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct SQLIST {
	int * pdata;
	int length = 0;//有效数据长度
	int Maxsize = 20;//申请空间(最大长度)
}SqList, *pSqList;
void InitSqList(pSqList pL1, pSqList pL2, pSqList pL3);//初始化
void Traverse(pSqList pL);//遍历
void MergeTwo(pSqList pL1, pSqList pL2, pSqList pL3);//合并两个表
int main(void) {
	SqList L1,L2,L3;
	InitSqList(&L1, &L2, &L3);
	Traverse(&L1);
	Traverse(&L2);
	printf_s("合并:\n");
	MergeTwo(&L1, &L2, &L3);
	Traverse(&L3);
	return 0;
}
void InitSqList(pSqList pL1, pSqList pL2, pSqList pL3) {
	pL1->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
	pL2->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
	pL3->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
	if (pL1->pdata == NULL) {
		printf_s("pL1动态分配空间失败!\n");
		exit(-1);
	}
	if (pL2->pdata == NULL) {
		printf_s("pL2动态分配空间失败!\n");
		exit(-1);
	}
	if (pL3->pdata == NULL) {
		printf_s("pL3动态分配空间失败!\n");
		exit(-1);
	}
	int a1[5] = { 2,3,4,6,8};
	int a2[7] = { 3,5,6,7,8,9,15};
	for (int i = 0; i < sizeof(a1) / sizeof(int); i++) {
		pL1->pdata[i] = a1[i];
		pL1->length++;
	}
	for (int i = 0; i < sizeof(a2) / sizeof(int); i++) {
		pL2->pdata[i] = a2[i];
		pL2->length++;
	}
}
void Traverse(pSqList pL) {
	int i = 0;
	if (pL->length == 0) {
		printf_s("表为空!\n");
		exit(-1);
	}
	for (i; i < pL->length; i++) {
		printf_s("%d	", pL->pdata[i]);
	}
	printf_s("\n");
	return;
}
void MergeTwo(pSqList pL1, pSqList pL2, pSqList pL3) {
	int i=0, j=0,k=0;
	if ((pL1->length + pL2->length) > pL3->Maxsize) {
		printf_s("两个表长度之和超出最大范围!\n");
		exit(-1);
	}
	while (i < pL1->length&&j < pL2->length) {
		if (pL1->pdata[i] <= pL2->pdata[j])
			pL3->pdata[k++] = pL1->pdata[i++];
		else
			pL3->pdata[k++] = pL2->pdata[j++];
	}
	while (i < pL1->length) {
		pL3->pdata[k++] = pL1->pdata[i++];
	}
	while (j < pL2->length) {
		pL3->pdata[k++] = pL2->pdata[j++];
	}
	pL3->length = k;
	return;
}

运行结果:
在这里插入图片描述

8、题目8:已知一维数组A[m+n]中依次存放两个线性表(a1,a2,,am),和(b1,b2,,,bn)。试编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,,,bn)放在(a1,a2,,am)前面。

#include <stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct SQLIST {
	int * pdata;
	int length = 0;//有效数据长度
	int Maxsize = 20;//申请空间(最大长度)
}SqList, *pSqList;
void InitSqList(pSqList pL1, pSqList pL2, pSqList pL3);//初始化
void Traverse(pSqList pL);//遍历
void MergeTwo(pSqList pL1, pSqList pL2, pSqList pL3);//合并两个表
int GetLength(pSqList pL);//获取顺序表的长度
void Reverse(pSqList pL, int left, int right);//倒置
int main(void) {
	SqList L1, L2, L3;
	InitSqList(&L1, &L2, &L3);
	printf_s("L1:	");
	Traverse(&L1);
	printf_s("L2:	");
	Traverse(&L2);
	printf_s("合并L3:	");
	MergeTwo(&L1, &L2, &L3);
	Traverse(&L3);
	int m = GetLength(&L1);
	int n = GetLength(&L2);
	printf_s("实现L1和L2位置的交换:\n");
	Reverse(&L3, 0, m + n - 1);
	Reverse(&L3, 0, n - 1);/*第一次整体倒置后,前m个现在是后m个并为倒置的;
	原第二部分即后n个现在是前n个,且为倒置的,此时要分别把两部分的次
	序恢复,此时的第一部分再倒置一次,第二部分在倒置一次。
	*/
	Reverse(&L3, n, m + n - 1);
	Traverse(&L3);
	return 0;
}
void InitSqList(pSqList pL1, pSqList pL2, pSqList pL3) {
	pL1->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
	pL2->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
	pL3->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
	if (pL1->pdata == NULL) {
		printf_s("pL1动态分配空间失败!\n");
		exit(-1);
	}
	if (pL2->pdata == NULL) {
		printf_s("pL2动态分配空间失败!\n");
		exit(-1);
	}
	if (pL3->pdata == NULL) {
		printf_s("pL3动态分配空间失败!\n");
		exit(-1);
	}
	int a1[5] = { 1,2,3,4,5 };
	int a2[7] = { 6,7,8,9,10,11,12 };
	for (int i = 0; i < sizeof(a1) / sizeof(int); i++) {
		pL1->pdata[i] = a1[i];
		pL1->length++;
	}
	for (int i = 0; i < sizeof(a2) / sizeof(int); i++) {
		pL2->pdata[i] = a2[i];
		pL2->length++;
	}
}
void Traverse(pSqList pL) {
	int i = 0;
	if (pL->length == 0) {
		printf_s("表为空!\n");
		exit(-1);
	}
	for (i; i < pL->length; i++) {
		printf_s("%d	", pL->pdata[i]);
	}
	printf_s("\n");
	return;
}
void MergeTwo(pSqList pL1, pSqList pL2, pSqList pL3) {
	int i = 0, j = 0, k = 0;
	if ((pL1->length + pL2->length) > pL3->Maxsize) {
		printf_s("两个表长度之和超出最大范围!\n");
		exit(-1);
	}
	while (i < pL1->length&&j < pL2->length) {
		if (pL1->pdata[i] <= pL2->pdata[j])
			pL3->pdata[k++] = pL1->pdata[i++];
		else
			pL3->pdata[k++] = pL2->pdata[j++];
	}
	while (i < pL1->length) {
		pL3->pdata[k++] = pL1->pdata[i++];
	}
	while (j < pL2->length) {
		pL3->pdata[k++] = pL2->pdata[j++];
	}
	pL3->length = k;
	return;
}
int GetLength(pSqList pL) {
	int l = pL->length;
	return l;
}
void Reverse(pSqList pL, int left, int right) {
	if (pL->length == 0) {
		printf_s("顺序表为空!\n");
		exit(-1);
	}
	int i = left, j = right;
	int t = 0;
	for (i, j; i < j; i++, j--) {
		t = pL->pdata[i];
		pL->pdata[i] = pL->pdata[j];
		pL->pdata[j] = t;
	}
}

运行结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Evekkan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值