删除顺序表中给定范围内元素

线性表算法题(4)

Posted by HK on September 26, 2020

题目 1

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

算法思路

因为题目中说的是有序表,所以删除的元素必然是相连的整体

先找值大于等于s的第一个元素(第一个删除的元素),然后寻找值大于t的第一个元素(最后一个删除的元素的下一个元素),要将这段元素删除,只需要直接将后面的元素前移。

算法

错误做法:没有整体删除,以及没有考虑所有元素值大于等于s的情况(这个只是顺序表下的解法,有序表要单独考虑)

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

正确答案:

bool Del_s_t1(Sqlist &L,Elemtype s,Elemtype t){
	int i,j;
	if(s>=t||L.length==0){
		return false;
	}
	for(int i=0;i<L.length&&L.data[i]<s;i++);	//寻找值大于等于s的第一个元素,当前i为这个元素的下标
	if(i>=L.length)		return false;			//所有元素值均小于s,返回
	for(j=i;j<L.length&&L.data[i]<=t;j++);		//寻找值大于t的第一个元素,当前j为其下标
	for(;j<L.length;i++,j++){
		L.data[i]=L.data[j];					//前移,填补被删元素位置
	}
	L.length=i+1;	//数组下标是从0开始的,此时i为最后一个前移元素的下标					
	return true;
}

题目2

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

算法思路

从前向后扫描顺序表L,用k记录下元素值在s到t之间元素的个数(初始时k=0)。对于当前扫描的元素,若其值不在s到t之间,则前移k个位置;否则执行k++。由于这样每个不在s到t之间的元素仅移动一次,所以算法效率高。

算法

bool Del_s_t2(Sqlist &L,Elemtype s,Elemtype t){
	int k=0;
	if(s>=t||L.length<0)
		return false;					//线性表为空或s、t不合法
	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];		//当前元素前移k个位置
	}
	L.length=L.length-k;				//长度减小
	return true;
}