数据结构——线性表相关算法题

一、【问题描述】

1.设顺序表用数组A[ ]表示,表中元素存储在数组下标0~m+n-1的范围内,前m个元素递增有序,后n个元素也递增有序,设计一个算法,使得整个顺序表有序。
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C或C++语言描述算法,并在关键之处给出注释。
(3)说明你所设计的算法的时间复杂度和空间复杂度。

2.已知递增有序的单链表A、B (A、B中元素个数分别为m、n,且A、B都带有头结点)分别存储了一个集合,请设计算法,以求出两个集合A和B的差集A-B (仅由在A中出现而不在B中出现的元素所构成的集合)。将差集保存在单链表A中,并保持元素的递增有序性。
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C或C++语言描述算法,并在关键之处给出注释。
(3)说明你所设计的算法的时间复杂度。

二、【问题解答】

1.答案:
(1)算法的基本设计思想
将数组A[ ]中的m+n个元素(假设元素为int型)看成两个顺序表:表L和表R。将数组当前状态看作起始状态,即此时表L由A[ ]中前m个元素构成,表R由A[ ]中后n个元素构成。要使A[ ]中m+n个元素整体有序,只需将表R中的元素逐个插入表L中的合适位置即可。
插入过程:取表R中的第一个元素A[m]存入辅助变量temp中,让temp逐个与A[m-1], … A[0]
进行比较,当temp<A[j] (0≤j≤m-1)时,将A[]后移-一位, 否则将temp存入A[j+1]中。重复上述过程,继续插入A[m+1],A[m+2], …,A[m+n], 最终A[]中元素整体有序。
(2)算法描述

void insertElem(int A[],int m,int n){
	int i,j;
	int temp;
	for(i=m;i<m+n;++i){
		temp=A[i];
		for(j=i-1;j>=0&&temp<A[j];--j){
			A[j+1]=A[j];//元素后移,以便腾出一个位置插入temp
		}
		A[j+1]=temp;//插入temp,由于for循环后j多前移了以为,因此在j+1处插入
	}
}

(3)算法的时间和空间复杂度
1)本题的规模由m和n共同决定。取最内层循环中A[j+1]=A[i];这一句作为基本操作,其执行次数在最坏的情况下为R中的每个元素都小于L中的所有元素:又因R中元素递增有序,所以对于每个R中的元素,要将其插入正确位置都必须进行m次移动,R中共有n个元素,因此有:f (m,n) =mn。
因此,本算法的时间复杂度为O(mn)。
2)算法所需额外存储空间与数据规模m和n无关,变化属于常量级,因此空间复杂度为0(1)。

2.答案:
(1)算法的基本设计思想
只需从A中删去A与B中共有的元素即可。由于两个链表中的元素是递增有序的,因此可以这么做:设置两个指针p、q开始时分别指向A和B的开始结点。循环进行以下判断和操作:如果p所指结点的值小于q所指结点的值,则p后移一位;如果q所指结点的值小于p所指结点的值,则q后移一位;如果两者所指结点的值相同,则删除p所指结点。最后,p与q任一指针NULL时算法结束。
(2)算法描述

void difference(LNode *A,LNode *B){
	LNode *p=A->next,*q=B->next;
	LNode *pre=A;
	LNode *r;
	while(p!=NULL&&q!=NULL){
		if(p->data<q->data){
			pre=p;
			p=p->next;
		}
		else if(p->data>q->data)
		q=q->next;
		else{
			pre->next=p->next;
			r=p;
			p=p->next;
			free(r);
		}
	}
}

(3)算法的时间复杂度分析
由算法描述可知,算法规模由m和n共同确定。算法中有一个单层循环,循环内的所有操作都是常数级的,因此可以用循环执行的次数作为基本操作执行的次数。可见循环执行的次数即为p、q两指针沿着各自链表移动的次数,考虑最坏的情况,即p、q都走完了自己所在的链表,循环执行m+n次,因此
时间复杂度为O(m+n)。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值