1.题目
设计并验证以下算法:带头结点单向循环链表L中的数据元素为整数且非递增有序,删除L中所有值大于mink且小于maxk的元素(若表中存在这样的元素),并将删除后链表L分解成两个带头结点单向循环链表L1、L2,使两个链表中各自仅含奇数或偶数。
(1) 根据键盘输入数据用头插法建立带头结点单向循环链表L。
(2) 利用原带头结点单向循环链表L的结点空间构成链表L1、L2。
(3) 输出带头结点单向循环链表L、删除后的链表L、拆分后的带头结点单向循环链表L1、L2。
代码如下:
#include <stdio.h>
#include<stdlib.h>
#define ARRAY_SIZE 100//数组容量
typedef int ElemType;
typedef struct List{
ElemType elem;
struct List *next;
}Listtype,*list;
Listtype* InitList();
void Insert(Listtype* L,ElemType elem);
void ConditionRemove(Listtype* head,ElemType min,ElemType max);
void Swap(Listtype *r, Listtype *p);
void SplitList(Listtype* head1,Listtype**head3);
void Output(Listtype *p);
int main(){
Listtype *head1,*head2;
int min,max;
printf("请输入一个递增整数序列:\n");
head1=InitList();
do{
int data;
scanf("%d",&data);
Insert(head1,data);
}while(getchar()!='\n');
printf("原链表L:\n");
Output(head1);
printf("请输入mink:\n");
scanf("%d",&min);
printf("请输入maxk:\n");
scanf("%d",&max);
ConditionRemove(head1,min,max);
printf("删除后的链表L:\n");
Output(head1);
SplitList(head1,&head2);
printf("拆分后的链表L:\n");
printf("L1:");
Output(head1);
printf("L2:");
Output(head2);
return 0;
}
Listtype* InitList(){//初始化链表
Listtype *L;
L=(list)malloc(sizeof(Listtype));
L->next=L; //头指针初始指向自己
return L;
}
void Insert(Listtype* L,ElemType elem){//添加元素
Listtype* r,*p;
p=L;
r=(list)malloc(sizeof(Listtype));//创建新节点
r->elem = elem;
r->next = p->next;//插入头节点后一个元素的前面
p->next = r;
}
void ConditionRemove(Listtype* head,ElemType min,ElemType max){ //除去符合条件的元素
Listtype *p,*r,*m;
m=head;
p=head->next;
while(p!=head){
if(p->elem<max){
while(p!=head){
if(p->elem<=min){
m->next=p;//符合条件,直接删去中间的结点
break;
}
if(p->next==head&&p->elem>min){//若遍历至结尾,依然大于min,则直接接头节点
m->next=head;
}
p=p->next;
}
break;
}
m=m->next;
p=p->next;
}
}
void SplitList(Listtype* head,Listtype**head2){//拆分链表
Listtype *p,*p1,*p2,*r,*r1,*r2,*m;
p=p1=head->next;
if(p==head){//考虑到没有数时需要闭合空的头节点
m=(list)malloc(sizeof(Listtype));
*head2=m;
m->next=*head2;
}
while(p!=head){
r=p->next;
while(r!=head){
if(p->elem%2!=0 && r->elem%2==0){//左边第一个结点为奇数,发现偶数时,交换
Swap(r,p);
break;
}
r=r->next;
}
p=p->next;
}
r1=head;//考虑到没有偶数时的情况
while(p1!=head){
if(p1->elem%2!=0){//遍历,直到找到奇数的结点
p2=(list)malloc(sizeof(Listtype));//创建头节点
*head2=p2;
p2->next=p1;
while(p1!=head){//遍历至结尾
r2=p1;//日记录前一个节点,为了得到尾节点
p1=p1->next;
}
r2->next=*head2;//尾节点与head2连接
r1->next=head;//r1与头节点head连接
break;
}
r1=p1;
p1=p1->next;
}
}
void Swap(Listtype *r, Listtype *p) {//交换两个节点中的信息
Listtype temp;
temp.elem = r->elem;
r->elem = p->elem;
p->elem = temp.elem;
}
void Output(Listtype *head){//输出
if(head->next==head){
printf("null\n");
}
else{
Listtype *p = head->next;
while(p!=head){
printf("%d ",p->elem);
p=p->next;
}
printf("\n");
}
}