第二章算法设计题

1设线性表存放在向量A[arrsize]的前elenum个分量中,且递增有序。试写一算法,将x插入到线性表的适当位置上,以保持线性表的有序性,并且分析算法的时间复杂度。

【提示】直接用题目中所给定的数据结构(顺序存储的思想是用物理上的相邻表示逻辑上的相邻,不一定将向量和表示线性表长度的变量封装成一个结构体),因为是顺序存储,分配的存储空间是固定大小的,所以首先确定是否还有存储空间,若有,则根据原线性表中元素的有序性,来确定插入元素的插入位置,后面的元素为它让出位置,(也可以从高下标端开始一边比较,一边移位)然后插入x ,最后修改表示表长的变量。

int insert(int A[],int *elenum,int x){
	if(*elenum==arrsize-1)return 0;
	else{
		i=*elenum;
		while(i>=0&&A[i]>x){
			A[i+1]=A[i];
			i--;
		}
		A[i+1]=x;
		(*elenum)++;
		return 1;
	}
}

2已知一顺序表 A,其元素值非递减有序排列,编写一个算法删除顺序表中多余的值相同的元素。

【提示】对顺序表 A,从第一个元素开始,查找其后与之值相同的所有元素,将它们删除;再对第二个元素做同样处理,依此类推。

void delete(SeqList *A){
	i=0;
	while(i<A->last){
		k=i+1;
		while(k<=A->last&&A->data[i]==A->data[k]){
			k++;
		}
		n=k-i-1;
		for(j=k;j<=A->last;j++){
			A->data[j-n]=A->data[j];
		}
		A->last=A->last-n;
		i++;
	}
}

3写一个算法,从一个给定的顺序表 A 中删除值在 x~y(x<=y)之间的所有元素,要求以较高的效率来实现。

【提示】对顺序表 A,从前向后依次判断当前元素 A->data[i]是否介于 x 和 y 之间,若是,并不立即删除,而是用 n 记录删除时应前移元素的位移量;若不是,则将 A->data[i]向前移动 n 位。n 用来记录当前已删除元素的个数。

void delete(SeqList *A,int x,int y){
	i=0;
	n=0;
	while(i<=A->last){
		if(A->data[i]>=x&&A->data<=y){
			n++;
		}
		else{
			A->data[i-n]=A->data[i];
			i++;
		}
		A->last=A->last-n;
	}
}

4.线性表中有 n 个元素,每个元素是一个字符,现存于向量 R[n]中,试写一算法,使 R 中的字符按字母字符、数字字符和其它字符的顺序排列。要求利用原来的存储空间,元素移动次数最小。

【提示】对线性表进行两次扫描,第一次将所有的字母放在前面,第二次将所有的数字放在字母之后,其它字符之前。

int zimu(char c){
	if(c>='a'&&c<='z'||c>='A'&&c<='Z'){
		return 1;
	}
	else {
		return 0;
	}
}
int number(char c){
	if(c>='0'&&c<='9'){
		return 1;
	}
	else{
		return 0;
	}
}
void process(char R[n]){
	low=0;
	high=n-1;
	while(low<high){
		while(low<high&&zimu(R[low]))low++;
		while(low<high&&!zimu(R[high]))high--;
		if(low<high){
			k=R[low];
			R[low]=R[high];
			R[high]=k;
		}
	}
	low=low+1;
	high=n-1;
	while(low<high){
		while(low<high&&number(R[low]))low++;
		while(low<high&&!number(R[high]))high--;
		if(low<high){
			k=R[low];
			R[low]=R[high];
			R[high]=k;
		}
	}
}

5线性表用顺序存储,设计一个算法,用尽可能少的辅助存储空间将顺序表中前 m 个元素和后 n 个元素进行整体互换。即将线性表:(a1, a2, … , am, b1, b2, … , bn)改变为:
(b1, b2, … , bn , a1, a2, … , am)。

【提示】比较 m 和 n 的大小,若 m<n,则将表中元素依次前移 m 次;否则,将表中元素依次后移 n 次。

void process(SeqList *L,int m,int n){
	if(m<=n){
		for(i=1;i<=m;i++){
			x=L->data[0];
			for(k=1;k<=L->last;k++){
				L->data[k-1]=L->data[k];
			}
			L->data[L->last]=x;
		}
		else{
			for(i=1;i<n;i++){
				x=L->data[L->next];
				for(k=L->last-1;k>=0;k--){
					L->data[k+1]=L->data[k];
				}
				L->data[0]=x;
			}
		}
	}
	
}

6已知带头结点的单链表 L 中的结点是按整数值递增排列的,试写一算法,将值为 x 的结点插入到表 L 中,使得 L 仍然递增有序,并且分析算法的时间复杂度。

LinkList insert(LinkList L,int x){
	p=l;
	while(p->next&&x>p->next->data){
		p=p->next;
	}
	s=(LNode*)malloc(sizeof(LNode));
	s->data=x;
	s->next=p->next;
	p->next=s;
	return(L);
}

7假设有两个已排序(递增)的单链表 A 和 B,编写算法将它们合并成一个链表 C 而不改变其排序性。

LinkList combine(LinkList A,LinkList B){
	C=A;//将新生成的链表C初始化为链表A,这样新链表一开始就包含了链表A的头节点。
	rc=C;//rc是一个指向链表C当前最后一个节点的指针,初始时也指向链表C的头节点。
	
	pa=A->next;
	pb=B->next;
	free(B);
	while(pa&&pb){
		if(pa->data<pb->data){
			rc->next=pa;
			rc=pa;
			pa=pa->next;
		}
		else{
			rc->next=pb;
			rc=pb;
			pb=pb->next;
		}
		if(pa) rc->next=pa;
		else rc->next=pb;
		return(C);
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

云 无 心 以 出 岫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值