线性表的链式存储结构

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");
		}
}

2.读入数据


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值