1.线性表算法题

1.

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

算法大致思想是扫描整个顺序表寻找最小值,辅助变量k为记录最小值位置方便最后填补。出错点在最后需要删除最后一个元素(L.length–)属实语文理解水平不行了。。。

bool DeleteElem(SqList &L,int &e){
	if(L.length==0){
		printf(“出错了!”);
		return false;
	}
	int k=0,i;
	e=L.data[0];
	for(i=1;i<L.length;i++){
		if(L.data[i]<min)
			e=L.data[i];
			k=i;				//记录是哪个位置的元素最小
	}
	L.data[k]=L.data[length-1];
	L.length--;  				//记得删除
	return true;
}

2.

顺序表中的元素逆置,要求空间复杂度为O(1)

大概思想是把顺序表劈成两半,然后交换对应位置的元素。长度是偶数奇数都可以用length/2来实现。

void ListReverse(SqList &L)
	int i,k;
	for(i=0;i<L.length/2;i++{		//判断条件不能➕等号,当length是奇数时候中间元素可以自己交换,但是偶数时就多交换了一次
		k=L.data[i];
		L.data[i]=L.data[L.length-i-1];
		L.data[L.length-i-1]=k;
	}	
}

3.

长度为n的顺序表L,要求删除所有值为x的数据元素。时间复杂度O(n),空间复杂度O(1)
方法1:

时间复杂度要求O(n),不能套双循环前移元素。空间复杂度要求O(1)不能新开辟数组。
所以最优的方法是在原数组上改造,把每一个不等于x的元素重新组成这个数组。

void DeleteElemX(Sqlist &L,ElemType x){
	int i,k=0;
	for(i=0;i<n;i++){
		if(L.data[i]!=x){			//注意找出不等于x的那些数组元素(而不是等于x)
			L.data[k]=L.data[i];
			k++;
		}
	}
	L.length=k;
}	

方法2:

用k记录等于x的元素个数,然后将不等于x的元素前移k位置。

void DeleteElemX(Sqlist &L,ElemType x){
	int i,k=0;
	for(i=0;i<n;i++){
		if(L.data[i]==x)
			k++;
		else
			L.data[i-k]=L.data[i];
		i++;
	}
	L.length=L.length-k;
}

emmm虽然能看懂但是想不出来。。

4.

从有序表中删除其值在s与t之间的所有元素,要求s<t。若线性表为空或者st值不合理退出运行。

注意是有序表,元素是有顺序的!

bool Delete_st(Sqlist &L,ElemType s,ElemType t){
	if(L.length==0||s>=t)
		return false;
	int i,j,k=0,n=0;
	for(i=0;i<L.length;i++){		
		if(L.data[i]==s){	//先找到等于s的元素的数组下标放到i中(记录位置)
			k=1;
			break;
		}
	}
	if(k=0)
		return false;		  //没有介于s到t之间的元素,直接返回。
	for(j=i;j<L.length;j++){  //找到大于t的第一个元素
		if(L.data[j]>t)
			break;
	}
	for(;j<L.length;i++,j++)	//前移,干掉前面的元素
		L.data[i]=L.data[j];
	L.length=i;
	return true;
}

感觉这道题比较抽象需要画图。
请添加图片描述

5.

从顺序表中删除其值在s与t之间的所有元素,要求s<t。若线性表为空或者st值不合理退出运行。

顺序表中删除,注意和上题区别。

bool Delete_st(Sqlist &L,ElemType s,ElemType t){
	if(L.length==0||s>=t)
		return false;
	int i,j,k=0;
	for(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;
}

这个方法也适用于上题。

6.

删除有序顺序表中值重复的元素。

bool DeleteElem(SqList &L){
	if(L.length==0)
		return false;
	int i,j,temp,k=0;
	temp=L.data[0];
	for(i=1;i<L.length;i++){
		if(L.data[i]==temp)
			k++;
		else{
			temp=L.data[i];
			L.data[i-k]=L.data[i];
			}
	}
	L.length=L.length-k;
	return true;
}

验证一下:

#include <stdio.h>
typedef struct {
	int data[8];	//顺序表元素
	int length;				//顺序表当前长度
}SqList;					//类型定义
void CreateList(SqList &L)
{
	int i;
	for (i = 0; i < L.length; i++)
	{//通过循环将数组元素全部遍历放入顺序表中
		scanf_s("%d", &L.data[i]); //输入方式
	}
}
bool DeleteElem(SqList &L) {
	if (L.length == 0)
		return false;
	int i, temp, k = 0;
	temp = L.data[0];
	for (i = 1; i < L.length; i++) {
		if (L.data[i] == temp)
			k++;
		else {
			temp = L.data[i];
			L.data[i - k] = L.data[i];
		}
	}
	L.length = L.length - k;
	return true;
}
int main()
{
	int i, j;
	SqList L;
	L.length = 8;
	CreateList(L);
	DeleteElem(L);
	for (j = 0; j < L.length; j++)
		printf("%d ", L.data[j]);
	return 0;
}

在这里插入图片描述

7.*

两个有序顺序表合为一个新的有序表。(算法典型,需要掌握!!)

i和j分别看成两个游标,当被选中放入p表后,游标向后移动直到遍历完顺序表为止。(这样可以做到每一个元素都经过了比较,如果只有一个游标则会丢失元素)
需要注意两个表的长度不一样,短的先遍历完,长的需要继续放入p表中。

SqList MergeList(SqList& L, SqList& M) {
	int i,j,k;
	SqList p;
	p.length = L.length + M.length;
	for (i = 0,j = 0,k = 0; i < L.length &&j < M.length;k++) { //注意逻辑关系是“与”
		if (L.data[i] < M.data[j]) {
			p.data[k] = L.data[i];
			i++;
		}
		else {
			p.data[k] = M.data[j];
			j++;
		}
	}
	if (i < L.length)
		for (; i < L.length; i++) {
			p.data[k] = L.data[i];
			k++;
		}
	else
		for (; j < M.length; j++) {
			p.data[k] = M.data[j];
			k++;
		}
	return p;
}

验证:
在这里插入图片描述

8.

一维数组A[M+N]中包含两个线性表,函数功能为将两个线性表位置交换。

为了验证方便,全部统一为顺序表了。
运用反转函数,反转三次顺序表。第一次反转全部,然后分别反转两个子顺序表。
注意反转函数传入的变量:假如第一个表长度为3,第二个长度为4.经过一次反转函数后从3+4变为4+3.

void ReverseList(SqList &L, int m, int n) {
	int i,j=0,temp;
	for (i = m-1; j < (n-m+1)/2; i++,j++) {
		temp = L.data[i];
		L.data[i] = L.data[n + m - i-2];
		L.data[n + m - i - 2] = temp;
	}
}
	ReverseList(L,1,M+N);
	ReverseList(L, 1, M);
	ReverseList(L, M+1, M+N);

在这里插入图片描述

9.

已知线性表中的元素有序递增,要求函数完成在表中查找数值为x的元素。若找到,则将其与后续元素位置交换,若找不到,则将其插入表中并使表中元素仍递增有序。

void Find_X(SqList& L, int x) {
	int i,j,k=0;
	for (i = 0; i < L.length; i++) {
		if (L.data[i] == x)
		{
			L.data[i] = L.data[i + 1];
			L.data[i + 1] = x ;
			break;
		}
		if (L.data[i] < x && L.data[i+1] > x)
		{
			k = 1;
			break;
		}
	}
	if (k == 1) {
		L.length = L.length + 1;
		for (j = L.length-1; j > i+1; j--) {
			L.data[j] = L.data[j-1];		//向后移动
		}
		L.data[i + 1] = x;
	}
}

验证:
取X=6
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值