分数 5
作者 李卫明
单位 杭州电子科技大学
1.2 编写程序,在第1题(第1题:编写程序,建立2个带头结点单链表,输入若干整数将正整数插入第1个单链表,将负整数插入第2个单链表,插入前和插入后单链表保持递增或相等次序,显示2个单链表,最后销毁。程序不可存在内存泄漏。)基础上合并2个单链表,合并前后单链表保持递增或相等次序,显示合并前后单链表。注意不可存在内存泄漏。。
输入格式:
若干整数。
输出格式:
每个单链表输出占一行,元素间用分隔符分隔;共3行
输入样例:
100 2 3 -2 -8 -6 -9 -10 50 2 -1
输出样例:
2->2->3->50->100
-10->-9->-8->-6->-2->-1
-10->-9->-8->-6->-2->-1->2->2->3->50->100
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
栈限制
8192 KB
C程序如下:
#include<stdio.h>
#include<stdlib.h> typedef struct LinkList { int Data; struct LinkList *Next;
} LinkList, *List; List CreatHead();//创建单链表
void Display(List L);//输出单链表
void Destroy(List L);//销毁单链表
void Sort(List L);//将单链表按从小到大的顺序排列
void Merge(List A,List B,List C);//将A和B合并为C(不创建新的结点)int main() {List firstHead, firstTail,secondHead,secondTail,third;firstHead = CreatHead();//创建第一个单链表的头结点firstTail = firstHead;//第一个尾巴指针指向第一个单链表的头结点secondHead = CreatHead();//创建第二个单链表的头结点secondTail = secondHead;//让第二个尾巴指针指向第二个单链表的头结点third = CreatHead();//创建第三个单链表的头结点int v;while (scanf("%d", &v) != EOF) {//scanf成功读取数据时返回EOF,读取失败时返回-1if (v > 0) {//当我们在scanf函数中输入CTRL + Z时,结束 scanf 函数,达到控制循环的目的。List L = CreatHead();//创建一个新结点L->Data = v;//让其数据域赋值为vfirstTail->Next = L;//尾指针的Next域指向新结点firstTail = L;//更新尾指针}else {List L = CreatHead();L->Data = v;secondTail->Next = L;secondTail = L;}}Sort(firstHead);//排序Sort(secondHead);Display(firstHead);//输出单链表Display(secondHead);Merge(firstHead,secondHead,third);//合并两个单链表Display(third);//输出合并后的单链表Destroy(third);//销毁单链表Destroy(firstHead);//这里采用创建新结点的方式合并两个单链表,因此最后需要将三个单链表全部销毁Destroy(secondHead);
}List CreatHead() { List p = (List)malloc(sizeof(LinkList)); //向内存申请空间if (p == NULL) { exit(EXIT_FAILURE); // 分配失败时退出 } p->Next = NULL; //p的Next域赋值为空return p; //返回p指针所指向的地址
} void Display(List L) {List p = L->Next; //p指向L的Next域,即第一有效结点while (p) { //若链表不为空printf("%d", p->Data); //输出数据p = p->Next; //p指向下一有效结点if (p) printf("->"); //若该结点不为空则输出“->”} //根据题目要求的输出结果printf("\n"); //换行
}void Destroy(List L) { List p = L; //p指向该单链表的头结点while (p->Next) { //p的下一结点为空时退出循环List q = p->Next; //要删除的结点为头节点的下一个结点,即第一有效结点,记录下来这个结点的地址p->Next = q->Next; //头结点指向要删除结点的下一个结点free(q); //删除该结点}//循环结束时只剩头结点free(p);//删除头结点
} void Sort(List L) {//选择排序List pStar, pcur,pMin;pStar = L->Next;//pStar指向第一有效结点int temp;//临时变量for (;pStar != NULL;pStar = pStar->Next) {//外循环pMin = pStar;//假设最小为pStar,即每次外循环的第一个结点for (pcur = pMin->Next;pcur != NULL; pcur = pcur->Next) {//内循环从pStar的下一个结点开始if (pcur->Data < pMin->Data) {pMin = pcur;//若找到更小则将其地址赋值给pMin}}if (pStar != pMin) {//若最小值地址与最初假设的不同则进行交换temp = pMin->Data;pMin->Data = pStar->Data;pStar->Data = temp;}}
}void Merge(List A, List B, List C) {List pTail = C;//尾指针指向C的头结点A = A->Next;//指向第一有效结点B = B->Next;//指向第一有效结点while (A && B) {//若A和B链表都不为空if (A->Data < B->Data) {//将更小的值加入新链表中List NewNode = CreatHead();NewNode->Data = A->Data;pTail->Next = NewNode;pTail = NewNode;A = A->Next;//加入后指针指向下一个结点}else {List NewNode = CreatHead();NewNode->Data = B->Data;pTail->Next = NewNode;pTail = NewNode;B = B->Next;}}while (A) {//将剩下的数据依次加入到新结点List NewNode = CreatHead();NewNode->Data = A->Data;pTail->Next = NewNode;pTail = NewNode;A = A->Next;}while (B) {List NewNode = CreatHead();NewNode->Data = B->Data;pTail->Next = NewNode;pTail = NewNode;B = B->Next;}
}