【问题描述】编写一个程序,将两个元素从小到大有序的一维数组归并成一个有序的一维数组。
【输入形式】用户在第一行输入第一个有序数组的元素数目,以回车结束此输入。然后在第二行按照刚才输入的元素数目依次输入数组元素,中间用空格分隔,最后用回车结束输入。第三行和第四行只需重复刚才的步骤,将第二个有序数组也输入即可。输入时候一定是有序输入的,即数组元素已经按照从小到大顺序排列。
【输出形式】程序将两个有序一维数组合并为一个有序数组并按照从小到大顺序输出。每个元素输出时用空格分隔,最后一个输出之后没有空格。
【样例输入】
6
2 5 8 11 20 35
4
1 6 15 60
【样例输出】1 2 5 6 8 11 15 20 35 60
【样例说明】第一行输入为第一个有序数组的元素数目,第二行为有序数组元素;第三行为第二个有序数组的元素数目,第四行为有序数组元素。
【评分标准】结果完全正确得20分。提交程序名为:arraysort.c
方法一:数组
数组方法1:
将两组数据全部输入到同一个数组中,然后进行排序,输出;
代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int num[2] = { 0 }, shuru[50] = { 0 };
int i, j = 0, m;//循环变量
//输入
for (i = 0; i < 2; i++)
{
scanf("%d", &num[i]);
for (; j < num[0] + num[1]; j++)
{
scanf("%d", &shuru[j]);
}
}
// 插入排序 从大到小
for (i = 0; i < num[0] + num[1]; ++i)
{
int end = i;//有序数列最后一个元素下标
shuru[num[0] + num[1]] = shuru[end + 1];
while (end >= 0)
{
if (shuru[num[0] + num[1]] < shuru[end])//向后移
{
shuru[end + 1] = shuru[end];
end--;
}
else
break;
}
shuru[end + 1] = shuru[num[0] + num[1]];
}
for (i = 0; i < j; i++)
printf("%d ", shuru[i]);
return 0;
}
数组方法2:
定义两个数组,长度够长(20左右) 依次载入数据
设计一个比较算法:
如果数组1已经比较结束,则接下来全输出数组2:数组2同理.
如果两个数组都没输出完,则比较当前位置上,数组1的数据和数组2的数据哪个大,哪个小输出哪个,再将该数组下标++;
提示:数组动态创建可用 malloc 函数实现 malloc(sizeof(int)*Length);
代码略~
方法二:单链表
单链表方法1:
尾插法生成单链表 新建一个单链表,依次合并插入数据,最后输出新的单链表.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode
{
int data;
struct LNode* next;
} LNode, * LinkList;
// 创建单链表头节点
LinkList CreateList()
{
return (LinkList)malloc(sizeof(LNode));
}
// 尾插法
void CreateListWithCount(LinkList L, int count)
{
L->next = NULL;
int i = 0;
for (; i <count; i++)
{
int value;
scanf("%d", &value);
LNode* newNode = (LNode*)malloc(sizeof(LNode));
newNode->data = value;
newNode->next = L->next;
L->next = newNode;
L = L->next; // debug 少了这句话就倒序,逐链表输出!!!!!
}
}
//递归
LinkList MergeList(LinkList L1, LinkList L2)
{
if (L1 == NULL)
return L2;
if (L2 == NULL)
return L1;
LinkList MergedList; //合并的链表
if (L1->data <= L2->data)
{
MergedList = L1;
MergedList->next = MergeList(L1->next, L2);
}
else
{
MergedList = L2;
MergedList->next = MergeList(L1, L2->next);
}
return MergedList;
}
/*
// 合并两个有序单链表
LinkList MergeList(LinkList L1, LinkList L2)
{
LinkList MergedList = CreateList();
LNode* p1 = L1->next;
LNode* p2 = L2->next;
LNode* tail = MergedList;
while (p1 && p2) //不为空
{
if (p1->data <= p2->data)
{
tail->next = p1;
p1 = p1->next;
}
else
{
tail->next = p2;
p2 = p2->next;
}
tail = tail->next;
}
tail->next = p1 ? p1 : p2;
free(L1);
free(L2);
return MergedList;
}
*/
// 打印链表
void PrintList(LinkList L)
{
LNode* s = L->next;/头节点为空 输出地址 若不适用递归 则: LNode* p = L->next; 就行
LNode* p = s->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
// 释放链表内存
void FreeList(LinkList L)
{
LNode* temp;
while (L->next)
{
temp = L->next;
L->next = L->next->next;
free(temp);
}
free(L);
}
int main()
{
int count1, count2;
// 输入第一个数组的大小
scanf("%d", &count1);
LinkList L1 = CreateList();
CreateListWithCount(L1, count1); // 创建第一个有序链表
// 输入第二个数组的大小
scanf("%d", &count2);
LinkList L2 = CreateList();
CreateListWithCount(L2, count2); // 创建第二个有序链表
LinkList MergedList = MergeList(L1, L2); // 合并链表
PrintList(MergedList); // 打印合并后的链表
// 释放链表内存
FreeList(MergedList);
return 0;
}
另外一种写法:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct LNode //链表定义
{
int data;
struct LNode* next;
}*LinkList, LNode;
//带头结点的初始化
bool InitList(LinkList & L) {
L = (LNode*)malloc(sizeof(LNode));
if (L == NULL) {
return true;
}
L->next = NULL;
return true;
}
//尾插法创建一个单链表
bool TailInsert(LinkList L) // L是指向定义的LNode结构体的指针
{
int num = 0;//元素个数
int ele = 0;//数据
LNode* p = L;
printf("请输入你要插入的元素个数:\n");
scanf("%d", &num);
int i = 0;
for (; i < num; i++) {
printf("请输入第%d个元素: ", i + 1);
scanf("%d", &ele);
LNode* s = (LNode*)malloc(sizeof(LNode));
if (s == NULL) {
return false;
}
s->data = ele;
s->next = NULL;
p->next = s;
p = p->next;
}
return true;
}
//合并两个单链表
LinkList mergeList(LinkList L1, LinkList L2) {
LNode* head = (LNode*)malloc(sizeof(LNode));
LNode* p1 = L1->next; //扫描指针p1指向第一个链表
LNode* p2 = L2->next; //扫描指针p2指向第二个链表
LNode* pre = head; //记录前驱结点
while (p1 != NULL && p2 != NULL) {
if (p1->data <= p2->data) { //按降序进行连接
pre->next = p1;
p1 = p1->next;
}
else {
pre->next = p2;
p2 = p2->next;
}
pre = pre->next;
}
pre->next = p1 == NULL ? p2 : p1;
return head;
}
//遍历一个单链表
void TranverseLinkList(LinkList L) {
LNode* p = L->next;
printf("单链表序列为:");
while (p != NULL) {
printf("%d ", p->data);
p = p->next;
}
}
int main() {
LinkList L1 = NULL;
LinkList L2 = NULL;
InitList(L1);
InitList(L2);
TailInsert(L1);
TailInsert(L2);
LinkList L3 = mergeList(L1, L2);
TranverseLinkList(L3);
}
单链表方法2:
一边比较两个单链表,一边输出数据.原理与数组类似,代码略
//关于 #define _CRT_SECURE_NO_WARNINGS
在VS里面,不可直接使用scanf 否则会报 sacnf 不安全 或 scanf返回值被忽略
解决方法添加该句话 或者将scanf 改为 scanf_s 但是scanf_s交作业时候编译不通过qwq~ 交作业时候删去_s即可(略显麻烦
标签:LNode,合并,数组,next,LinkList,L2,有序,L1,线性表 From: https://blog.csdn.net/m0_54369037/article/details/137403270