#include #include #include typedef struct LNode { int data; //数据域 struct LNode *next; //指针域 }LNode,*LinkList; // LinkList为指向LNode类型的指针类型 // 初始化四个链表L、M、N、H void chushihua(LinkList &L, LinkList &M, LinkList &N, LinkList &H) { //todo list 1: 为四个链表分配头节点并初始化 L = (LinkList)malloc(sizeof(LNode)); L->next = NULL; M = (LinkList)malloc(sizeof(LNode)); M->next = NULL; N = (LinkList)malloc(sizeof(LNode)); N->next = NULL; H = (LinkList)malloc(sizeof(LNode)); H->next = NULL; printf("链表初始化成功!\n"); } // 判断链表L是否为空表 void Emp(LinkList &L) { if (L->next == NULL) //todo list 2: 判断头节点的next是否为空 printf("链表为空表。\n"); else printf("链表为非空表。\n"); } // 求表长,返回L中数据元素个数 void Length(LinkList L){ LNode *p; //申请临时变量p p = L->next; //p指向第一个结点(首元结点) int length = 0; //todo list 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; int i; // 循环变量声明 for (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) //如果p的下一个节点是NULL(即链表为空或p指向链表的最后一个节点) //todo list 4: 直接插入新节点 L->next = q; else //如果链表不为空或p不是指向链表的最后一个节点,则进入这个else块(查找新节点的插入位置) { while (p->next != NULL && p->next->data < q->data) { //todo list 5: p指针不断往后移动 p = p->next; if (p->next == NULL) break; } //todo list 6: 插入*q结点 q->next = p->next; p->next = q; } } printf("数据插入完成!\n"); } // 显示链表L的所有元素 void xianshi(LinkList &L) { LNode *p; //申请临时变量p //LinkList p; p = L; 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; p = L->next; //todo list 7: p指针指向第一个数据节点 // 初始化M和N链表 M->next = NULL; N->next = NULL; LNode *m_tail = M; // M链表的尾指针 LNode *n_tail = N; // N链表的尾指针 while (p != NULL) { if (p->data % 2 == 0) //找出偶数元素,用尾插法将这些偶数元素建立成一个【偶数链表】 { o = (LinkList)malloc(sizeof(LNode)); //todo list 8: 使用尾插法插入偶数节点 o->data = p->data; o->next = NULL; n_tail->next = o; n_tail = o; } else //找出奇数元素,用尾插法将这些奇数元素建立成一个【奇数链表】 { j = (LinkList)malloc(sizeof(LNode)); //todo list 9: 使用尾插法插入奇数节点 j->data = p->data; j->next = NULL; m_tail->next = j; m_tail = j; } //todo list 10: p指针往后移动 p = p->next; } printf("奇数链表为:"); xianshi(M); printf("偶数链表为:"); xianshi(N); } // 3、合并一个递减链表:将奇数链表J和偶数链表O合并为一个新的链表H,合并时保持元素的有序性。 void hebiao(LinkList &J, LinkList &O, LinkList &H) { // 先将两个链表转换为数组,然后排序,最后用头插法创建递减链表 int data[100]; // 假设最多100个元素 int count = 0; LNode *p; int i, j; // 循环变量声明 LNode *t; // 收集奇数链表的数据 p = J->next; while (p != NULL) { data[count++] = p->data; p = p->next; } // 收集偶数链表的数据 p = O->next; while (p != NULL) { data[count++] = p->data; p = p->next; } // 对数据进行升序排序(从小到大)- 这样头插后会变成降序 for (i = 0; i < count - 1; i++) { for (j = i + 1; j < count; j++) { if (data[i] > data[j]) { // 如果前一个元素大于后一个元素,交换它们 int temp = data[i]; data[i] = data[j]; data[j] = temp; } } } // 使用头插法创建递减链表 H->next = NULL; for (i = 0; i < count; i++) { t = (LinkList)malloc(sizeof(LNode)); t->data = data[i]; t->next = H->next; H->next = t; } 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)); // 初始化链表 head->next = NULL; ji->next = NULL; ou->next = NULL; he->next = NULL; int choose = -1, n; printf("*********************************************\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("请输入您的选择:"); scanf("%d", &choose); switch (choose) { case 1: chushihua(head, ji, ou, he); break; case 2: printf("请输入要插入的整数个数:"); scanf("%d", &n); charu_1(head, n); break; case 3: fenbiao(head, ji, ou); break; case 4: hebiao(ji, ou, he); break; case 5: printf("当前(递增)单链表内容为:"); xianshi(head); break; case 6: Length(head); break; case 7: Emp(head); break; case 0: printf("程序已退出,感谢使用!\n"); exit(0); break; default: printf("输入错误,请重新输入!\n"); break; } } return 0; }