实验题目:线性表的链式存储结构
1.设计并验证以下算法:带头结点单向链表L中的数据元素为整数且非递增有序,删除L中所有值大于mink且小于maxk的元素(若表中存在这样的元素),并将删除后链表L分解成两个带头结点单向链表L1、L2,使两个链表中各自仅含奇数或偶数。
要求
- 根据键盘输入数据用头插法建立带头结点单向循环链表L。
- 利用原带头结点单向链表L的结点空间构成链表L1、L2。
- 输出带头结点单向链表L、删除后的链表L、拆分后的带头结点单向链表L1、L2。
审题
- 要实现链表L中的数据元素非递增有序,且用头插法建立链表L,那么输入该是非递增有序的
- 删除操作中等于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);
}