数据结构实验二

实验题目:线性表的链式存储结构

1.设计并验证以下算法:带头结点单向链表L中的数据元素为整数且非递增有序,删除L中所有值大于mink且小于maxk的元素(若表中存在这样的元素),并将删除后链表L分解成两个带头结点单向链表L1、L2,使两个链表中各自仅含奇数或偶数。

要求
  1. 根据键盘输入数据用头插法建立带头结点单向循环链表L。
  2. 利用原带头结点单向链表L的结点空间构成链表L1、L2。
  3. 输出带头结点单向链表L、删除后的链表L、拆分后的带头结点单向链表L1、L2。
审题
  1. 要实现链表L中的数据元素非递增有序,且用头插法建立链表L,那么输入该是非递增有序的
  2. 删除操作中等于mink,maxk的数不用删除
算法思路

头节点创建链表咱就不说了。

1.删除L中所有值大于mink且小于maxk的元素
 p=L;
 while(p->next->data<=mink)
     p=p->next;

第一步,先让p指针移动到要删除的节点前,也就是p的下一个指针中的data是
要大于mink的,所以当p->next->data<=mink,让p=p->next

		q=p->next;
		while(q->data<maxk&&q){
			p->next=q->next;//让指针指向待删除节点q的下一个节点
			free(q);//释放q节点所占的内存
			q=p->next;//让q指向下一个要判断的节点

第二步,让q指针在p的后面,如果q里面的data是小于maxk的,那么就把q节点删了,删掉的方法就是,让指针指向待删除节点q的下一个节点,然后释放q节点所占的内存最后让q指向下一个要判断的节点,如此循环,直到q中data大于maxk,q不是要删除的节点为止,或者q不存在了为止。

2.奇偶拆分

大概思路是,设置一个L2节点作为奇数表的头节点,那么L也就是L1就是偶数表的头节点了,接下来遍历一遍L,把单数data的节点删除接到L2上就是了。

pa=L,pb=L2,p=L->next;//p是pa后一个节点
	while(p){
		if(p->data%2==0)
			pa=p,p=p->next;
		else
			pa->next=p->next,pb->next=p,pb=p,p=pa->next;
		
	}

具体说一下怎么把单数data节点删除接到L2上,也就是循环中else的操作。

pa->next=p->next;//让指针指向待删除节点q的下一个节点

删除操作和上一题的异曲同工,接上也就是让pb的next域指向p,然后pb,p后移。
要注意的是理解pa,pb在算法中的作用和意义。

详细代码
#include<stdio.h>
#include<stdlib.h>

typedef struct word sw;
struct word{
	int data;
	sw *next;
};
//非递增有序,输入非递减有序 
sw *head_build()
{
	sw *head,*p,*q;
	int a,n;
	head=(sw *)malloc(sizeof(sw));
	head->next=NULL;
	printf("请输入要输入的元素个数\n"); 
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a);
		p=(sw *)malloc(sizeof(sw));
		p->data=a; 
		if(head->next == NULL)
		{
			head->next=p;
			p->next=NULL;
		}	
		else
		{
			q=head->next;
			head->next=p;
			p->next=q;
		}
	}
	return head;
}
//删除L中所有值大于mink且小于maxk的元素
void *del_list(sw *L,int mink,int maxk)
{
	sw *p=L;
	while(p->next->data<=mink)
		p=p->next;
	sw *q=p->next;
	//while(q&&q->data<=mink)
	//	q=q->next;
	//p->next=q;
	//if(p->next){
		q=p->next;
		while(q->data<maxk&&q){
			p->next=q->next;
			free(q);
			q=p->next;
		//}
	}
	return L;
}
//奇偶拆分
sw* split(sw *L)
{
	sw *pa,*pb,*p,*L2;
	L2=(sw *)malloc(sizeof(sw));
	pa=L,pb=L2,p=L->next;
	while(p){
		if(p->data%2==0)
			pa=p,p=p->next;
		else
			pa->next=p->next,pb->next=p,pb=p,p=pa->next;
		
	}
	pb->next=NULL;
	return L2;
}

void show(sw* head)
{
	head=head->next;
	for(;head!=NULL;head=head->next)
	{
		printf("%d ",head->data);
	}
	printf("\n");
}

int main()
{
	sw *L,*L1,*L2;
	L=head_build();
	show(L);
	del_list(L,3,7);
	show(L);
	L2=split(L);
	show(L);
	show(L2);
} 

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值