王道代码练习-(链表)

Problem1:/*设计递归算法,删除不带头结点的单链表L中的值为x的结*/
void solve1(LNode *L,x){
	LNode *p=NULL;
	if(L==NULL)
	return 0;
	if(L->data==x){
		p=L;
		L=L-next;
		free(p);
		solve1(L,x); 
	}
	else{
		solve1(L->next,x);
	}
}

Problem2:/*在带头结点的单链表中,删除所有值为x的结点,并释放其空间*/
Solution:/*用p遍历链表,pre始终指向p的前驱节点,若与x相等,则删除*/
void solve2(LNode *L){
	LNode *p=L->next;
	LNode *pre=L,q=NULL;
	while(p!=NULL){
		if(p->data==x){
			q=p;
			p=p->next;
			pre->next=p;
			free(q);
		}
		else{
			pre=p;
			p=p->next;
		}
	}
} 


Problem3:/*设L为带头结点的单链表,编写算法实现从尾到头反向输出结点值*/
Solution1:/*采用递归方式访问链表结点,当访问完最后一个结点时再开始输出*/
solve3(LNode *L){
	if(L->next!=NULL){
		solve10(L->next);
	}
	if(L!=NULL)
	print(L->data);
}
Solution2:/*采用栈的方法,先让结点入栈,再出栈,便可颠倒输出顺序*/
void solve3(LNode *L){
	LNode *p=L->next;
	LNode *stack[max]={NULL}:
	LNode *q=NULL;
	int top=-1;
	while(p!=NULL){
		stack[++top]=p;
		p=p->next;
	}
	while(top>-1){
		q=stack[top--];
		print(q->data);
	}
}

Problem4:/*在带头结点的单链表中,删除值最小的结点*/
void solve4(LNode *L){
	LNode *p=L->next;
	LNode *pre=L;
	LNode *minpre=pre;
	int min=INFMax;
	while(p!=NULL){
		if(p->data<min){
			min=p->data;
			minpre=pre;
		}
		pre=p;
		p=p->next;
	}
}

Problem5:/*将带头结点的单链表就地逆置,即要求辅助空间复杂度为O(1)*/
Solution:/*先将头结点摘下,再将头结点后面的元素头插到头结点上*/
void solve5(LNode *L){
	LNode *p=L->next;
	LNode *q=NULL;
	L->next=NULL;
	while(p!=NULL){
		r=p;
		p=p->next;
		r->next=L->next;
		L->next=r;
	}
}

Problem6:/*对于一个带头结点的单链表L,设计一个算法使其元素递增有序*/
Solution:/*采用直接插入排序法,先保留头结点及其后面的一个结点构成初始的有序单链表
         ,然后用指针p遍历剩余的无序链表,再依次将无序链表中的结点插到有序链表中的
		 合适位置,直到无序链表中不再有结点为止*/
void solve6(LNode *L){
	LNode *p=L->next->next;
	LNode *pre;
	L->next->next=NULL;
	while(p!=NULL){
		r=p-next;
		pre=L;//每次都从有序链表的第一个结点开始,从前往后比较 
		while(pre!=NULL&&p->data>pre->next->data)
		    pre=pre->next;
		p->next=pre->next;
		pre->next=pre;
		p=r;
	}
}

Problem7:/*给定一个带头结点的单链表,结点元素为整型,要求按递增顺序输出
         结点元素,并释放结点所占存储空间*/
Solution:/*用指针p遍历链表,每次都从头开始遍历,每遍历完一轮,就找出该轮
中值最小的结点,然后输出,并释放该节点所占空间,重复上述步骤,直到链表为
空时结束。minp指向最小结点,minpre指向其前驱结点*/          
void solve7(LNode *L){
	LNode *p,*pre;
	LNode *minp,*minpre;
	while(L->next!=NULL){
		pre=L;
		p=L->next;
		minp=p;
		minpre=pre;//之前漏了这一步 
		while(p!=NULL){
			if(p->data<minp->data){
				minp=p;
				minpre=pre;
			}
			else{
				pre=p;
				p=p->next;
			}
		}
		printf("%d\t",minp->data);
		minpre->next=minp->next;
		free(minp);
	}
	free(L);
}


Problem8:/*有一个递增有序的单链表,要求删除其重复元素,只保留每个重复元素中的一个即可*/
Solution:/*因为链表已经是递增有序的,所以重复的元素一定是相邻的*/
void solve8(LNode *L){
	LNode *p=L->next;
	LNode *q;
	while(p!=NULL){
		q=p->next;
		if(q->data==p->data){
			p->next=q->next;//这里是p->next在移动 
			free(q);
		}
		else{
			p=p->next;
		}
	}
} 

Problem9:/*设A,B是两个递增有序的单链表,要求找他们的公共元素,然后插在
但链表C的后面,不破坏A,B链表*/
Solution:/*依次比较A,B的元素,若不相等,则让值小的指针往后移,若值相等,则
将该结点尾插到C链表后面,然后再让两个指针一起后移*.重复上述过程,直到其中
一个链表先遍历完就停止*/
LNode *solve9(LNode *A,LNode *B){
	LNode *p=A->next;
	LNode *q=B->next;
	LNode *C,*r,*s;
	C=(LNode *)malloc(sizeof(LNode));
	r=C;
	while(p!=NULL&q!=NULL){
		if(p->data<q->data)
		p=p->next;
		if(q->data<p->data)
		q=q->next;
		if(q->data==p->data){
		s=(LNode *)malloc(sizeof(int));
		s->data=p->data;
		r->next=s;
		r=s;
		p=p->next;
		q=q->next;	
		}
	}
	r->next=NULL;
	return C;
}

Problem10:/*设单链表L=(a1,a2,a3,...,an-1,an),重新排列,使其变为
L'=(a1,an,a2,an-1,a3,...)*/
Solution:/*L'是由L先挑第一个元素,再挑倒数第一个元素依次合并成的,
step1:先找中间结点,为此设置两个指针p,q。p每走一步,q就走两步,当
q走到链尾时,p便走到链表中间;
step2:再将链表L后半段的元素原地逆置;
step3:*/
void solve10(LNode *L){
	LNode *p=L->next;
	LNode *q=L->next;
	LNode *q,*r;
	while(q->next!=NULL){
		p=p->next;
		q=q->next;
		if(q->next!=NULL)
		q=q->next;
	}
	q=p->next;//此处P已经位于链表的中点
	p->next=NULL;//暂时将链表前后切分 
	while(q!=NULL){//逆置链表后半段 
		r=q->next;//先保存q的下一个结点
		q->next=p->next;
		p->next=q;
		q=r;//更新q
	}
	s=L->next;
	q=p->next;
	while(q!=NULL){
		r=q->next;
		q->next=s->next;
		s->next=q;
		s=q->next;//s是变化的,每次新插入到结点都接到s后面 
		q=r;
	} 
}  
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值