王道单链表课后题

  1. 设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点
void Del_X_3(Linklist &L,ElemType x){
	LNode *p;
	if(L==NULL){
		return;
	}
	if(L->data==x){
		p=L;
		L=L->next;
		free(p);
		Dex_X_3(L,x);
	}else{
		Del_X_3(L->next,x);
	}
}
  1. 在带头结点的单链表L中,删除所有值为X的结点,并释放其空间,假设值为X的结点不唯一,试编写算法实现以上的操作
void Del_X_1(Linklist &L,ElemType x){
	LNode *pre=L,*p=L->next,*q;
	while(p->next!=null){
		if(p->data==X){
			q=p;
			p=p->next;
			pre->next=p;
			free(q);
		}else{
			pre=p;
			p=p->next;
		}
	}
}
  1. 设L为带头结点的单链表,编写算法实现从尾到头反向输出每个结点的值
void Lprint(Linklist &L){
	if(L->next!=NULL){
		Lprint(L->next);	
	}
	if(L!=null) print(L->data);
}
void R_Ignore_Head(Linklist &L){
	if(L->next!=NULL) Lprint(L->next);
}
  1. 试编写算法将带头结点的单链表就地逆置,指辅助空间复杂度为O(1)
void Reverse(Linklist L){
	LNode *pre,*p=L->next,*r=p->next;
	p->next=NULL;
	while(r!=NULL){
		pre=p;
		p=r;
		r=r->next;
		p-next=pre;
	}
	L->next=p;
	return L;
}
//使用前插法
LinkList Reverse(LinkList L){
	LNode *p,*r;
	p=L->next;
	L->next=NULL;
	while(p!=NULL){
		r=p->next;
		p->next=L->next;
		L->next=p;
		p=r;
	}
	return L;
}
  1. 试编写算法将带头结点的单链表L中删除一个最小值结点的高效算法
LinkList Delete_Min(LinkList &L){
	LNode *pre=L,*p=pre->next;
	LNode *minpre=pre,*minp=p;
	while(p!=NULL){
		if(p->data<minp->data){
			minp=p;
			minpre=pre;
		}
		pre=p;
		p=p->next;
	}
	minpre->next=minp->next;
	free(minp);
	return L;
}
  1. 有一个带头结点的单链表L,设计一个算法使其元素递增有序
void sort(LinkList &L){
	LNode *p=L->next,*pre;
	LNode *r=p->next;
	p->next=NULL;
	p=r;
	while(p!=NULL){
		r=p->next;
		pre=L;
		while(pre->next!=NULL&&pre->next->data<p->data){
			pre=pre->next;
		}
		p->next=pre->next;
		pre->next=p;
		p=r;
	}
}
  1. 设在一个带表头结点的单链表中所有的元素结点都无序,试编写一个函数删除表中所有介于给定两个之间的元素的元素
void RangeDelete(LinkList &L,int min,int max){
	LNode *pr=L,*p=L->next;
	while(p!=NULL){
		if(p->data>min&&p->data<max){
			pr->next=p->next;
			free(p);
			p=pr->next;
		}else{
			pr=p;
			p=p->next;
		}
	}
}
  1. 给定两个单链表,编写算法找出两个链表的公共结点
LinkList Search_lst_Common(LinkList L1.LinkList L2){
	int len1=Length(L1);
	int len2=Length(L2);
	LinkList longList,shortList;
 	if(len1>len2){ 
		longList=L1->next;
		shortList=L2->next;
		dist=len1-len2; 
 	else{ 
 		longList=L2->next;
 		shortList=L1->next;
 		dist=len2-len1;
 }
	while(dist--){
		longList=longList->next;
}
while(longList!=NULL){ 

	if(longList==shortList) return longList;
	 
	else{ 
		longList=longList->next;
		shortList=shortList->next;
		}
	}
	return NULL;
}

9.给定一个带表头结点的单链表,设head为头指针,结点结构为(data,next),data为整形元素,next为指针,试写出算法:按照递增次序输出单链表中各结点的数据元素,并释放结点所占的存储空间(要求:不允许舒勇数组作为辅助空间)

/*
算法思想:对链表进行遍历,在每次遍历中找出整个链表的最小值元素,输出并释放结点所占空间;再查找次小值元素,输出并释放空间,如此下去,直至链表为空,最后释放头结点所占 存储空间。该算法的时间复杂度为 O(n^2)。
*/
void MinDelete(LinkList &head){
	while(head->next!=NULL){
		LNode *pre=head;
		LNode *p=pre->next;
		while(p->next!=NULL){
			if(p->next->data<pre->next->data){
				pre=p;
			}
			p=p->next; 
		}
		print(pre->next->data);
		u=pre->next;
		pre->next=u->next;
		free(u);
	}
	free(head);
}
  1. 将一个带头结点的单链表A分解为两个带头结点的单链表A和B使得A表中含有原表中序号为基数的元素,而B表中含有原表中序号为偶数的元素,且保持相对顺序不变
LinkList DisCreat_1(LinkList &A){ 
	//将表A中结点按序号的奇偶性分解到表A或表B中
	int i=0//1记录表A中结点的序号 
	LinkList B=(LinkList)malloc(sizeof(LNode)); //创建B表表头 
	B->next=NULL//B表的初始化 
	LNode *ra=A,*rb=B,*p;//ra和rb将分别指向将创建的A表和B 表的尾结点 
	p=A->next; //p为链表工作指针,指向待分解的结点
	A->next=NULL; //置空新的A表
	while(p!=NULL){ 
		i++;//序号加1 
		if(i%2==0{ //处理序号为偶数的链表结点 
			rb->next=p; //在B表尾插入新结点 
			rb=p; //rb指向新的尾结点
		} else{ //处理原序号为奇数的结点 
			ra->next=p; //在A表尾插入新结点 
			ra=p;
		  }
			p=p->next; //将p恢复为指向新的待处理结点
			} //while结束 
			ra->next=NULL;
			rb->next=NULL;
			return B;
	}
  1. 设C={a1,b1,a2,b2,…,an,bn}为线性表采用带头结点的hc单链表存放设计一个算法将其拆分为两个为两个线性表使得A={a1,a2,a3…,an},B={b1,b2,b3…bn}.
LinkList DisCreat2(LinkList &A){ 
	LinkList B=(LinkList)malloc(sizeof(LNode));//创建B表表头
	B->next-NULL; //B表的初始化
	LNode*p=A->next,*qi;//p为工作指针
	LNode*ra=A; //ra始终指向A的尾结点 
	while(p!=NULL){ 
		ra->next=p;
		ra=p; //将*p链到A的表尾 
		p=p->next; 
		if(p!=null){ //头插后,*p将断链,因此用q记忆*p的后继 
			q=p->next;
			p->next=B->next; //将*p插入到B的前端 
			B->next=p; (
			p=q; //A尾结点的next域置空 
		}
	}
	ra->next=NULL;
	return B;
}
  1. 在一个递增有序的线性表中,有数值相同的元素存在。若存储的方式为单链表,设计算法去掉数值相同的元素使表中不再有重复元素
/*
	算法思想:由于是有序表,所有相同值域的结点都是相邻的。
	用p扫描递增单链表L,若*p 结点的值域等于其后继结点的值域,则删除后者,否则p移向下一个结点。
*/
void DelSame(LinkList&L){ 
	//L是递增有序的单链表,本算法删除表中数值相同的元素 
	LNode *p=L->next,*q; //p为扫描工作指针 
	if(p==NULLreturn;
	while(p->next!=NULL){ 
		q=p->next; //q指向*p的后继结点 
		if(p->data=q->data){ //找到重复值的结点
			p->next=q->next; //释放*q结点 
			free(q) //释放相同元素值的结点 
			} else {
				p=p->next;
			}
	}
}
  1. 假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。请编写算法将这两个单链表归并为按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表
/*
算法思想:两个链表已经按元素值递增次序排序,将其合并时,均从第一个结点起进行比较,
将小的结点链入链表中,同时后移工作指针。该问题要求结果链表按元素值递减次序排列,
故新 链表的建立应该采用头插法。比较结束后,可能会有一个链表非空,
此时用头插法将剩下的结点依次插入新链表中即可
*/
void MergeList(LinkList &La,LinkList &Lb){
	LNode *r,*pa=La->next,*pb=Lb->next;
	La->next=NULL;//当两链表均不为空时,循环 
	while(pa&&pb) 
		if(pa->data<-pb->data){ //r暂存pa的后继结点指针 
			r=pa->next; 
			pa->next=La->next; //将pa结点链于结果表中,同时逆置 
			La->next=pa;
			pa=r;
			}                  //恢复pa为当前待比较结点 
			else{//r暂存pb的后继结点指针 
				r=pb->next; 
				pb->next=La->next; //将pb结点链于结果表中,同时逆置 
				La->next=pb;  //恢复pb为当前待比较结点 
				pb=r;
			}
			if(pa) pb=pa; //通常情况下会剩一个链表非空,处理 剩下的部分 
			while(pb){ //处理剩下的一个非空链表 
				r=pb->next; //依次插入到La中(头插法) 
				pb->next-La->next;
				La->next=pb;
				pb=r;
			}
			free(Lb);
}

14.设A和B是两个带头结点的单链表,其中元素递增有序。设计一个算法从A和B中的公共元素产生链表C,要求不破坏A,B的结点。

//算法思想:表A、B都有序,可从第一个元素起依次比较A、B两表的元素,若元素值不等, 
//则值小的指针往后移,若元素值相等,则创建一个值等于两结点的元素值的新结点,
//使用尾插法 插入到新的链表中,并将两个原表指针后移一位,直到其中一个链表遍历到表尾
void Get_Common(LinkList A,LinkList B)(//本算法产生单链表A和B的公共元素的单链表C 
	LNode *p=A->next,*q=B->next,*r,*s; //r始终指向C的尾结点 
	LinkList C=(LinkList)malloc(sizeof(LNode));
	r=C;
	while(p!=NULL&&q!=NULL{ //循环跳出条件 
		if(p->data<q->data) p=p->next; //若A的当前元素较小,后移指针 
		elseif(p->data>q->data) 
			q=q->next; //若B的当前元素较小,后移指针
			else{ //找到公共元素结点
				s=(LNode*)malloc(sizeof(LNode));
				s->data=p->data;
				r->next=s;
				r=s;
				p=p->next;
				q=q->next;
			}
	}
	r->next=NULL;
}

15.已知两个链表A,B分别表示两个集合,其元素递增排序,编制函数求A,B的交集,并存放于A链表中

/*
算法思想:采用归并的思想,设置两个工作指针pa和pb,对两个链表进行归并扫描,
只同时出现在两集合中的元素才链接到结果表中且仅保留一个,
其他的结点全部释放。当一个链 遍历完毕后,释放另一个表中剩下的全部结点。 
*/
LinkList Union(LinkList &la,LinkList &lb)( 
	pa=la->next; //设工作指针分别为pa和pb 
	pb=lb->next;
	pc=la; //结果表中当前合并结点的前驱指针 
	while(pa&&pb){ 
		if(pa->data==pb->data){ //交集并入结果表中 
			pc->next=pa; //A中结点链接到结果表 
			pc=pa;
			pa=pa->next;
			u=pb;//B中结点释放 
			pb=pb->next;
			free(u);
		}
		else if(pa->data<pb->data){
				u=pa;
				pa=pa->next;
				free(u);
		}
		else {
			u=pb;
			pb=pb->next;
			free(u);
		}
	}
		while(pa){
			u=pa;
			pa=pa->next;
			free(u);
	}
		while(pb){
			u-pb;
			pb=pb->next;
			free(u);
	}
		pc->next=NULL;
		free(lb);
	return la;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值