246 lines
5.3 KiB
C++
246 lines
5.3 KiB
C++
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
typedef struct LNode
|
||
{
|
||
int data; // 数据域
|
||
struct LNode *next; // 指针域
|
||
} LNode, *LinkList; // LinkList为指向LNode类型的指针类型
|
||
|
||
void chushihua(LinkList &L, LinkList &M, LinkList &N, LinkList &H) // 初始化四个链表L、M、N、H
|
||
{
|
||
// 1.初始化链表,将各链表头节点的next设为NULL
|
||
L->next = NULL;
|
||
M->next = NULL;
|
||
N->next = NULL;
|
||
H->next = NULL;
|
||
printf("链表初始化完成\n");
|
||
}
|
||
|
||
void Emp(LinkList &L) // 判断链表L是否为空表
|
||
{
|
||
// 2.判断链表是否为空(头节点的next是否为NULL)
|
||
if (L->next == NULL)
|
||
printf("链表为空表。\n");
|
||
else
|
||
printf("链表为非空表。\n");
|
||
}
|
||
|
||
void Length(LinkList L)
|
||
{ // 求表长,返回L中数据元素个数
|
||
LNode *p; // 申请临时变量p
|
||
p = L->next; // p指向第一个结点(首元结点)
|
||
int length = 0;
|
||
// 3.遍历链表统计节点数量
|
||
while (p != NULL)
|
||
{
|
||
length++;
|
||
p = p->next;
|
||
}
|
||
printf("链表长度为:%d\n", length);
|
||
}
|
||
|
||
// 1、建立递增有序链表:向链表L中插入n个整数,插入时保持链表的有序性(从小到大)。
|
||
void charu_1(LinkList &L, int n)
|
||
{
|
||
LNode *q, *p;
|
||
for (int i = 1; i <= n; i++)
|
||
{
|
||
p = L; // 在每次循环开始时,将p指向链表的头节点L
|
||
q = (LinkList)malloc(sizeof(LNode)); // 为新的节点分配内存,并将q指向这块内存
|
||
printf("请输入第%d个整数数的值", i);
|
||
scanf("%d", &q->data); // 将输入的值存储在q指向的节点的data字段中
|
||
q->next = NULL; // 将新节点的next指针设置为NULL,表示新节点当前不指向任何节点。
|
||
|
||
if (p->next == NULL) // 如果链表为空,直接插入
|
||
{
|
||
// 4.空链表时直接插入新节点
|
||
p->next = q;
|
||
}
|
||
else // 非空链表,查找插入位置
|
||
{
|
||
while (p->next != NULL && p->next->data < q->data)
|
||
{
|
||
// 5.移动p指针找到插入位置
|
||
p = p->next;
|
||
}
|
||
// 6.插入新节点
|
||
q->next = p->next;
|
||
p->next = q;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 显示链表L的所有元素
|
||
void xianshi(LinkList &L)
|
||
{
|
||
LNode *p; // 申请临时变量p
|
||
p = L;
|
||
// 7.判断链表是否为空
|
||
if (p->next == NULL)
|
||
{
|
||
printf("链表为空");
|
||
}
|
||
while (p->next != NULL)
|
||
{
|
||
printf("%4d", p->next->data);
|
||
p = p->next;
|
||
}
|
||
printf("\n");
|
||
}
|
||
|
||
// 2、分解:将链表L中的元素分为奇数和偶数两个链表M和N,并分别显示它们。
|
||
void fenbiao(LinkList &L, LinkList &M, LinkList &N)
|
||
{
|
||
LNode *j, *o, *p, *temp;
|
||
p = L;
|
||
while (p->next != NULL)
|
||
{
|
||
// 8.移动p指针到下一个节点
|
||
temp = p->next;
|
||
p->next = temp->next; // 提前断开原链表连接,防止遍历混乱
|
||
|
||
if (temp->data % 2 == 0) // 偶数元素,前插法插入偶数链表
|
||
{
|
||
o = temp;
|
||
// 9.前插法插入偶数链表
|
||
o->next = N->next;
|
||
N->next = o;
|
||
}
|
||
else // 奇数元素,前插法插入奇数链表
|
||
{
|
||
j = temp;
|
||
// 10.前插法插入奇数链表
|
||
j->next = M->next;
|
||
M->next = j;
|
||
}
|
||
}
|
||
printf("奇表为:");
|
||
xianshi(M);
|
||
printf("偶表为:");
|
||
xianshi(N);
|
||
}
|
||
|
||
// 3、合并一个递减链表:将奇数链表J和偶数链表O合并为一个新的链表H,合并时保持元素的有序性。
|
||
void hebiao(LinkList &J, LinkList &O, LinkList &H)
|
||
{
|
||
LNode *p, *q, *t;
|
||
p = J->next; // 指向奇数链表第一个元素
|
||
q = O->next; // 指向偶数链表第一个元素
|
||
LNode *m = H; // 合并链表的尾指针
|
||
|
||
while (p != NULL && q != NULL) // 奇和偶表都有数据结点
|
||
{
|
||
if (p->data > q->data) // 奇数大于偶数,取奇数
|
||
{
|
||
t = (LinkList)malloc(sizeof(LNode));
|
||
t->data = p->data;
|
||
t->next = NULL;
|
||
// 11.尾插法插入合并链表
|
||
m->next = t;
|
||
m = t;
|
||
p = p->next; // 移动奇数链表指针
|
||
}
|
||
else // 偶数大于等于奇数,取偶数
|
||
{
|
||
t = (LinkList)malloc(sizeof(LNode));
|
||
t->data = q->data;
|
||
t->next = NULL;
|
||
// 12.尾插法插入合并链表
|
||
m->next = t;
|
||
m = t;
|
||
q = q->next; // 移动偶数链表指针
|
||
}
|
||
}
|
||
|
||
if (p == NULL) // 奇数链表先遍历完成,处理剩余偶数
|
||
{
|
||
while (q != NULL)
|
||
{
|
||
t = (LinkList)malloc(sizeof(LNode));
|
||
t->data = q->data;
|
||
t->next = NULL;
|
||
// 13.尾插剩余偶数节点
|
||
m->next = t;
|
||
m = t;
|
||
q = q->next;
|
||
}
|
||
}
|
||
|
||
if (q == NULL) // 偶数链表先遍历完成,处理剩余奇数
|
||
{
|
||
while (p != NULL)
|
||
{
|
||
t = (LinkList)malloc(sizeof(LNode));
|
||
t->data = p->data;
|
||
t->next = NULL;
|
||
// 14.尾插剩余奇数节点
|
||
m->next = t;
|
||
m = t;
|
||
p = p->next;
|
||
}
|
||
}
|
||
|
||
printf("从大到小的单链表为:");
|
||
xianshi(H); // 显示合表H
|
||
}
|
||
|
||
int main()
|
||
{
|
||
// 生成新结点作为头结点,用头指针分别指向各头结点
|
||
LinkList head = (LinkList)malloc(sizeof(LNode));
|
||
LinkList ji = (LinkList)malloc(sizeof(LNode));
|
||
LinkList ou = (LinkList)malloc(sizeof(LNode));
|
||
LinkList he = (LinkList)malloc(sizeof(LNode));
|
||
|
||
int choose = -1, n;
|
||
printf("*********************************************\n");
|
||
printf("********** 实验一 *******\n");
|
||
printf("*********************************************\n");
|
||
printf("********** 1.初始化单链表 *******\n");
|
||
printf("********** 2.建立递增链表 *******\n");
|
||
printf("********** 3.分成奇/偶两链表 *******\n");
|
||
printf("********** 4.合并成递减单链表 *******\n");
|
||
printf("********** 5.显示建立的(递增)单链表整体 *******\n");
|
||
printf("********** 6.求单链表长度 *******\n");
|
||
printf("********** 7.判断单链表是否为空 *******\n");
|
||
printf("********** 0.退出 *******\n");
|
||
printf("*********************************************\n");
|
||
while (choose)
|
||
{
|
||
printf("请输入你的选择项:\n");
|
||
scanf("%d", &choose);
|
||
switch (choose)
|
||
{
|
||
case 1:
|
||
chushihua(head, ji, ou, he);
|
||
break;
|
||
case 2:
|
||
printf("请输入你要插入正整数的个数:\n");
|
||
scanf("%d", &n);
|
||
charu_1(head, n);
|
||
break;
|
||
case 3:
|
||
fenbiao(head, ji, ou);
|
||
break;
|
||
case 4:
|
||
hebiao(ji, ou, he);
|
||
break;
|
||
case 5:
|
||
xianshi(head);
|
||
break;
|
||
case 6:
|
||
Length(head);
|
||
break;
|
||
case 7:
|
||
Emp(head);
|
||
break;
|
||
case 0:
|
||
exit(0);
|
||
break;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|