1.(必做题)设计并验证以下算法:带头结点单向循环链表L中的数据元素为整数且非递增有序,删除L中所有值大于mink且小于maxk的元素(若表中存在这样的元素),并将删除后链表L分解成两个带头结点单向循环链表L1、L2,使两个链表中各自仅含奇数或偶数。
(1) 根据键盘输入数据用头插法建立带头结点单向循环链表L。
(2) 利用原带头结点单向循环链表L的结点空间构成链表L1、L2。
(3) 输出带头结点单向循环链表L、删除后的链表L、拆分后的带头结点单向循环链表L1、L2。
//
// Created by CHAO on 2021-10-24.
//
//创建链表,删除链表,拆分链表
#include "stdlib.h"
#include "stdio.h"
typedef struct list {
int data;
struct list *next;
} List;
List *HeadInsert() { //头插法创建链表
int temp = 0;
List *head;
List *p1, *p2;
head = (List *) malloc(sizeof(List));
p1 = (List *) malloc(sizeof(List));
p2 = (List *) malloc(sizeof(List));
head->next = p1->next = p2->next = NULL;
while (1) {
scanf("%d", &temp);
if (temp != -1) {
p1->data = temp;
if (head->next == NULL) {
p2 = p1;
head->next = p2;
p2->next = head; //单向循环
} else {
p1->next = p2; //先连接好新的p1到p2前面,head后面
head->next = p1;
p2 = p1; //p1改名为p2
}
p1 = (List *) malloc(sizeof(List));
p1->next = NULL;
} else break;
}
return head;
}
void print(List *head) { //打印链表
List *temp = head->next;
while (temp != head) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
void Paixv(List *head) { //排序
List *p, *q;
int t;
p = head->next;
while (p != head) {
q = p->next;
while (q != head) {
if (p->data <= q->data) {
t = p->data;
p->data = q->data;
q->data = t;
}
q = q->next;
}
p = p->next;
}
}
void ListDelete(List *head, int min, int max) {
List *copy = head;
List *p = copy;
List *q = copy->next;
while (q != head) {
if (q->data >= min && q->data <= max) {
p->next= q->next;
q = q->next;
} else {
q = q->next;
p = p->next;
}
}
}
void ListChai(List *la, List *l1, List *l2) { ///拆分为奇偶链表
List *lb = la->next;
List *head, *head2;
List *p1, *p2, *p3, *p4;
head = l1;
p1 = (List *) malloc(sizeof(List));
p2 = (List *) malloc(sizeof(List));
head2 = l2;
p3 = (List *) malloc(sizeof(List));
p4 = (List *) malloc(sizeof(List));
head->next = p1->next = p2->next = NULL;
head2->next = p3->next = p4->next = NULL;
while (lb != la) {
p1->data = lb->data;
p3->data = lb->data;
if ((lb->data % 2) == 1) { //如果是奇数
if (head->next == NULL) {
p2 = p1;
head->next = p2;
} else {
p2->next = p1;
p2 = p1;
}
p1 = (List *) malloc(sizeof(List));
p1->next = NULL;
} else //如果是偶数
{
if (head2->next == NULL) {
p4 = p3;
head2->next = p4;
} else {
p4->next = p3;
p4 = p3;
}
p3 = (List *) malloc(sizeof(List));
p3->next = NULL;
}
lb = lb->next;
}
p2->next = head;
p4->next = head2;
}
int main() {
printf("开始创建链表L,(以-1结尾)\n");
List *L = HeadInsert();
printf("下面是处理后的递减链表\n");
Paixv(L);
print(L);
int mink = 0, maxk = 0;
printf("请输入mink和maxk的值\n");
scanf("%d", &mink);
scanf("%d", &maxk);
ListDelete(L, mink, maxk);
printf("删除后的链表元素为:");
print(L);
///拆分链表
List *L1, *L2;
L1 = (List *) malloc(sizeof(List));
L2 = (List *) malloc(sizeof(List));
ListChai(L, L1, L2);
if (L1->next == NULL) {
printf("L1表元素为空\n");
} else {
printf("拆分后的L1链表为:\n");
print(L1);
}
if (L2->next == NULL) {
printf("L2表元素为空");
} else {
printf("拆分后的L2链表为:\n");
print(L2);
}
}
1.用户在最开始时输入的数据时无序的,里面有自带的函数将它排序。
2.输入的最小值和最大值可以不是在链表元素中的,是任意值。
3.删除多余元素后的链表拆分为奇数链表和偶数链表,这两个链表为新创建的。