线性表综合应用题

tips:题目来源王道考研书数据结构篇

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

算法思想:搜索整个顺序表,查找最小值元素并记住其位置,搜索结束后用最后一个元素填补空出的原最小值元素的位置。

参考代码:

//1、从顺序表中删除具有最小元素值的元素(假设唯一),并由函数返回被删元素的值。
// 空出的位置由最后一个元素填补,若顺序表为空,则显示出错信息并退出运行。
#define MaxSize 50
#include<stdio.h>
typedef struct SqList {
	int data[MaxSize];
	int length;
};
void InitList(SqList &L) {
	L.length = 0;
}
bool ListInsert(SqList &L,int i,int e) {
	if (i<1 || i>L.length+1)
		return false;
	if (L.length >= MaxSize)
		return false;
	for (int j = L.length; j >= i; j--)
		L.data[j] = L.data[j - 1];
	L.data[i-1] = e;
	L.length++;
	return true;
}
bool Del_Min(SqList &L,int &e) {
	//首先判断表的长度,空表则返回错误并退出
	if (L.length == 0)
		return false;
	e = L.data[0];//假设最小的是L.data[0]
	int pos = 0;
	for (int i = 1; i < L.length; i++) {
		if (L.data[i] < e) {//将e分别和序列中每个数比较,比e小则赋值给e
			e = L.data[i];
			pos = i;//记录当前e对应L.data[index],index的值
		}
	}
	L.data[pos] = L.data[L.length-1];//将最后一位交换到删除的地方
	L.length--;
	return true;
}
int main() {
	SqList L1;
	InitList(L1);
	ListInsert(L1, 1, 1);
	ListInsert(L1, 2, 2);
	ListInsert(L1, 3, 3);
	ListInsert(L1, 4, 4);
	ListInsert(L1, 5, 5);
	for (int i = 0; i < L1.length; i++) {
		printf("%d\n", L1.data[i]);
	}
	//调用Del_Min()
	int	elem = 0;
	Del_Min(L1, elem);
	for (int i = 0; i < L1.length; i++) {
		printf("L1[%d]=%d\n", i, L1.data[i]);
	}
	printf("elem=%d\n", elem);
}

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

算法思想:扫描顺序表L的前半部分元素,对于元素L.data[i](0<=i<L.length/2),将其与后半段的对应元素L.data[L.length-i-1]进行交换

//设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)。
#define MaxSize 50
#include<stdio.h>
typedef struct SqList {
	int data[MaxSize];
	int length;
};
void InitList(SqList &L) {
	L.length = 0;
}
bool ListInsert(SqList &L,int i,int e) {
	if (i<1 || i>L.length+1)
		return false;
	if (L.length >= MaxSize)
		return false;
	for (int j = L.length; j >= i; j--)
		L.data[j] = L.data[j - 1];
	L.data[i-1] = e;
	L.length++;
	return true;
}
void ListReverse(SqList& L) {
	int temp = 0;
	for (int i = 0; i < L.length / 2; i++) {
		temp = L.data[L.length - i - 1];
		L.data[L.length - i - 1] = L.data[i];
		L.data[i] = temp;
	}
}
int main() {
	SqList L1;
	InitList(L1);
	ListInsert(L1, 1, 1);
	ListInsert(L1, 2, 2);
	ListInsert(L1, 3, 3);
	ListInsert(L1, 4, 4);
	ListInsert(L1, 5, 5);
	printf("原顺序表:\n");
	for (int i = 0; i < L1.length; i++) {
		printf("%d\n", L1.data[i]);
	}
	printf("翻转后:\n");
	ListReverse(L1);
	for (int i = 0; i < L1.length; i++) {
		printf("%d\n", L1.data[i]);
	}
}

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

代码:

//对长度为n的顺序表L,编写一个时间复杂的为O(n),空间复杂度为O(1)的算法,
// 该算法删除顺序表中所有值为x的数据元素
#define MaxSize 50
#include<stdio.h>
typedef struct SqList {
	int data[MaxSize];
	int length;
};
void InitList(SqList &L) {
	L.length = 0;
}
bool ListInsert(SqList &L,int i,int e) {
	if (i<1 || i>L.length+1)
		return false;
	if (L.length >= MaxSize)
		return false;
	for (int j = L.length; j >= i; j--)
		L.data[j] = L.data[j - 1];
	L.data[i-1] = e;
	L.length++;
	return true;
}

void Delx_1(SqList& L, int x) {
	int k = 0;
	for (int i = 0; i < L.length; i++) {
		if (L.data[i] != x) {
			L.data[k] = L.data[i];
			k++;
		}
	}
	L.length = k;
}

int main() {
	SqList L1;
	InitList(L1);
	ListInsert(L1, 1, 1);
	ListInsert(L1, 2, 2);
	ListInsert(L1, 3, 3);
	ListInsert(L1, 4, 2);
	ListInsert(L1, 5, 5);
	printf("原顺序表:\n");
	for (int i = 0; i < L1.length; i++) {
		printf("%d\n", L1.data[i]);
	}
	printf("删除顺序表中值为2的\n");
	Delx_1(L1,2);
	for (int i = 0; i < L1.length; i++) {
		printf("%d\n", L1.data[i]);
	}
}

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

参考代码:

//从顺序表中删除其值在定值s和t之间(包含s和t,要求s<t)的所有元素,
// 若s或t不合理或顺序表为空,则显示出错信息并退出运行。
#define MaxSize 50
#include<stdio.h>
typedef struct SqList {
	int data[MaxSize];
	int length;
};
void InitList(SqList &L) {
	L.length = 0;
}
bool ListInsert(SqList &L,int i,int e) {
	if (i<1 || i>L.length+1)
		return false;
	if (L.length >= MaxSize)
		return false;
	for (int j = L.length; j >= i; j--)
		L.data[j] = L.data[j - 1];
	L.data[i-1] = e;
	L.length++;
	return true;
}

bool Delx_2(SqList& L, int s,int t ) {
	if (L.length == 0 || s > t)
		return false;
	int k = 0;
	for (int i = 0; i < L.length; i++) {
		if (L.data[i] >= s && L.data[i] <= t)
			k++;
		else
			L.data[i - k] = L.data[i];
	}
	L.length = L.length - k;
	return true;
}

int main() {
	SqList L1;
	InitList(L1);
	ListInsert(L1, 1, 1);
	ListInsert(L1, 2, 2);
	ListInsert(L1, 3, 3);
	ListInsert(L1, 4, 2);
	ListInsert(L1, 5, 5);
	printf("原顺序表:\n");
	for (int i = 0; i < L1.length; i++) {
		printf("%d\n", L1.data[i]);
	}
	printf("删除顺序表中值在[2,3]范围内的值\n");
	Delx_2(L1,2,3);
	for (int i = 0; i < L1.length; i++) {
		printf("%d\n", L1.data[i]);
	}
}

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

//5、从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不相同。
#define MaxSize 50
#include<stdio.h>
typedef struct SqList {
	int data[MaxSize];
	int length;
};
void InitList(SqList &L) {
	L.length = 0;
}
bool ListInsert(SqList &L,int i,int e) {
	if (i<1 || i>L.length+1)
		return false;
	if (L.length >= MaxSize)
		return false;
	for (int j = L.length; j >= i; j--)
		L.data[j] = L.data[j - 1];
	L.data[i-1] = e;
	L.length++;
	return true;
}
//5、从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不相同。
bool Del_x3(SqList& L) {
	if (L.length == 0)
		return false;
	int i = 0;
	for (int j = 1; j < L.length; j++) {
		if (L.data[i] != L.data[j]) {
			i++;
			L.data[i] = L.data[j];
		}
	}
	L.length = i + 1;
}

int main() {
	SqList L1;
	InitList(L1);
	ListInsert(L1, 1, 1);
	ListInsert(L1, 2, 2);
	ListInsert(L1, 3, 2);
	ListInsert(L1, 4, 2);
	ListInsert(L1, 5, 5);
	printf("原顺序表:\n");
	for (int i = 0; i < L1.length; i++) {
		printf("%d\n", L1.data[i]);
	}
	printf("删除有序表中重复的值:\n");
	Del_x3(L1);
	for (int i = 0; i < L1.length; i++) {
		printf("%d\n", L1.data[i]);
	}
}

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

#define MaxSize 50
#include<stdio.h>
typedef struct SqList {
	int data[MaxSize];
	int length;
};
void InitList(SqList &L) {
	L.length = 0;
}
bool ListInsert(SqList &L,int i,int e) {
	if (i<1 || i>L.length+1)
		return false;
	if (L.length >= MaxSize)
		return false;
	for (int j = L.length; j >= i; j--)
		L.data[j] = L.data[j - 1];
	L.data[i-1] = e;
	L.length++;
	return true;
}
//6、将两个有序顺序表合并成一个新的有序顺序表,并由函数返回结果顺序表
bool Merge(SqList A, SqList B, SqList &C) {
	//将有序顺序表A和B合并成一个新的表C
	if (A.length + B.length > MaxSize)
		return false;
	int i = 0;
	int j = 0;
	int k = 0;
	while (i < A.length && j < B.length) {
		if (A.data[i] <= B.data[j]) {
			C.data[k] = A.data[i];
			k++;
			i++;
		}
		else
		{
			C.data[k] = B.data[j];
			k++;
			j++;
		}
	}
	//假设A还没比较完
	while (i < A.length){
		C.data[k++] = A.data[i++];
	}
	//同理假设B还没比较完
	while (j < B.length) {
		C.data[k++] = B.data[j++];
	}
	C.length = k;
	return true;
}

int main() {
	SqList L1, L2, L3;
	//初始化表
	InitList(L1);
	InitList(L2);
	InitList(L3);

	ListInsert(L1, 1, 1);
	ListInsert(L1, 2, 2);
	ListInsert(L1, 3, 3);
	ListInsert(L2, 1, 4);
	ListInsert(L2, 2, 5);
	ListInsert(L2, 3, 6);
	printf("有序顺序表L1\n");
	for (int i = 0; i < L1.length; i++) {
		printf("L1.data[%d]=%d\n", i, L1.data[i]);
	}
	printf("有序顺序表L2\n");
	for (int i = 0; i < L2.length; i++) {
		printf("L2.data[%d]=%d\n", i, L2.data[i]);
	}
	printf("L1和L2合并为有序顺序表L3\n");
	Merge(L1, L2, L3);
	for (int i = 0; i < L3.length; i++) {
		printf("L3.data[%d]=%d\n", i, L3.data[i]);
	}
}

7、已知有一组数组A[m+n]中依次存放两个线性表(a1,a2,a3,...,am)和(b1,b2,b3,...,bn),编写一个函数,将数组中两个顺序表的位置交换,即将(b1,b2,b3,...,bn)放在(a1,a2,a3,...,am)的前面。

算法思想:首先将数组A[m+n]中的全部元素(a1,a2,a3,...,am,b1,b2,b3,...,bn)原地逆置为(bn,bn-1,bn-2...b1,an,an-1,an-2...a1),然后分别对前n个元素和后m个元素逆置,即可得到(b1,b2,b3,...,bn,a1,a2,a3,...,am),从而实现位置交换。

参考代码:

#include<stdio.h>
typedef int DataType;
void Reverse(DataType A[], int left, int right,int arraySize) {
	if (left == right || right >= arraySize) {
		return;
	}
	int mid = (left + right) / 2;
	int temp = 0;
	for (int i = 0; i <= mid - left; i++) {
		temp = A[right - i];
		A[right - i] = A[left + i];
		A[left + i] = temp;
	}
}
void Exchange(DataType A[], int m, int n, int arraySize) {
	Reverse(A, 0, m + n - 1, arraySize);
	Reverse(A, 0, n - 1, arraySize);
	Reverse(A, n, m + n - 1, arraySize);
}
int main() {
	int A[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("原数组是\n");
	for (int i = 0; i < 10; i++) {
		printf("%d\n", A[i]);
	}
	printf("逆置后的数组是\n");
	Exchange(A,5,5,10);
	for (int i = 0; i < 10; i++) {
		printf("%d\n", A[i]);
	}
}

时间复杂度分析:O(n)

8、线性表(a1,a2,a3...,an)中的元素递增有序且按顺序存储于计算机内。要求设计一个算法,完成最少时间在表中查找数值为x的元素,若找到,则将其与后继元素位置相交换,若找不到,则将其插入到表中使表中元素仍递增有序。

算法思想:顺序存储的线性表递增有序,可以顺序查找也可以折半查找。题目要求最短时间,所以本题用折半查找法。

参考代码:

#define MaxSize 50
#include<stdio.h>
typedef struct SqList {
	int data[MaxSize];
	int length;
};
void InitList(SqList &L) {
	L.length = 0;
}
bool ListInsert(SqList &L,int i,int e) {
	if (i<1 || i>L.length+1)
		return false;
	if (L.length >= MaxSize)
		return false;
	for (int j = L.length; j >= i; j--)
		L.data[j] = L.data[j - 1];
	L.data[i-1] = e;
	L.length++;
	return true;
}
//线性表(a1,a2,a3...,an)中的元素递增有序且按顺序存储于计算机内。
// 要求设计一个算法,完成最少时间在表中查找数值为x的元素,
// 若找到,则将其与后继元素位置相交换,
// 若找不到,则将其插入到表中使表中元素仍递增有序。
void SearchExchangeInsert(SqList& L, int x) {
	int left = 0, right = L.length - 1,mid;
	//折半查找法
	while (left <= right) {
		mid = (left + right) / 2;
		if (L.data[mid] == x)
			break;//若为mid,直接退出循环
		else if (L.data[mid] < x) {
			right = mid - 1;//若小于则去左半部分查找
		}
		else{
			left = mid + 1;//若大于则去右半部分查找
		}
	}
	if (L.data[mid] == x && mid != L.length - 1) {//若找到,则将其与后继元素位置相交换
		int temp = L.data[mid];
		L.data[mid] = L.data[mid + 1];
		L.data[mid + 1] = temp;
	}
	if (left > right) {//若找不到,则将其插入到表中使表中元素仍递增有序
		int i;
		for (i = L.length - 1; i > right; i--) {
			L.data[i + 1] = L.data[i];
		}
		L.data[i + 1] = x;
		L.length++;
	}

	
}

int main() {
	SqList L1;
	//初始化表
	InitList(L1);

	ListInsert(L1, 1, 1);
	ListInsert(L1, 2, 2);
	ListInsert(L1, 3, 4);
	ListInsert(L1, 4, 4);
	ListInsert(L1, 5, 5);
	printf("有序顺序表L1\n");
	for (int i = 0; i < L1.length; i++) {
		printf("L1.data[%d]=%d\n", i, L1.data[i]);
	}
	printf("查找元素x:\n");
	SearchExchangeInsert(L1, 3);
	for (int i = 0; i < L1.length; i++) {
		printf("L1.data[%d]=%d\n", i, L1.data[i]);
	}
}

 9、给定三个序列A,B,C,长度均为n,且无重复元素的递增数列,请设计一个时间上尽可能高效的算法,逐行输出同时同时存在与这三个序列中的所有元素。例如,数组A为[1,2,3]数组B[2,3,4]数组C[-1,0,2],则输出2

算法思想:三个指针分别从数组起始位置开始遍历数组,找到当前三个指针中指向最大的数,其余两个指针分别右移

#define MaxSize 100
#include<stdio.h>
typedef struct SqList {
	int data[MaxSize];
	int length;
};
int GetMax(int a, int b);
void InitList(SqList& L);
void InitList(SqList& L) {
	L.length = 0;
}
bool ListInsert(SqList& L, int i, int e) {
	if (i<1 || i>L.length + 1)
		return false;
	if (L.length >= MaxSize)
		return false;
	for (int j = L.length-1; j >i; j--) {
		L.data[j] = L.data[j + 1];
	}
	L.data[i-1] = e;
	L.length++;
	return true;
}
//给定三个序列A,B,C,长度均为n,且无重复元素的递增数列,请设计一个时间上尽可能高效的算法,
//逐行输出同时同时存在与这三个序列中的所有元素。例如,数组A为[1,2,3]数组B[2,3,4]数组C[-1,0,2],则输出2。

void SearchSame(SqList L1, SqList L2, SqList L3, int n) {
	int i = 0, j = 0, k = 0;
	while(i<n&&j<n&&k<n){
		if (L1.data[i] == L2.data[j] && L2.data[j] == L3.data[k]) {
			printf("%d", L1.data[i]);
			i++;
			j++;
			k++;
		}
		else
		{
			int maxnum = GetMax(L1.data[i], (L2.data[j], L3.data[k]));
			if (L1.data[i] < maxnum)
				i++;
			if (L2.data[j] < maxnum)
				j++;
			if (L3.data[k] < maxnum)
				k++;
		}
	}
}
int GetMax(int a,int b) {
	if (a > b)
		return a;
	else
	{
		return b;
	}
}

int main() {
	SqList L1, L2, L3;
	InitList(L1);
	InitList(L2);
	InitList(L3);

	ListInsert(L1, 1, 1);
	ListInsert(L1, 2, 2);
	ListInsert(L1, 3, 3);
	ListInsert(L2, 1, 2);
	ListInsert(L2, 2, 3);
	ListInsert(L2, 3, 4);
	ListInsert(L3, 1, -1);
	ListInsert(L3, 2, 0);
	ListInsert(L3, 3, 2);

	SearchSame(L1, L2, L3, 3);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

陈啊尘

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

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

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

打赏作者

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

抵扣说明:

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

余额充值