8577 合并顺序表

8577 合并顺序表

题干

时间限制:1000MS 代码长度限制:10KB
提交次数:5339 通过次数:2251

题型: 编程题 语言: G++
Description
若线性表中数据元素相互之间可以比较,且数据元素在表中按值递增或递减,则称该表为有序表。

编写算法,将两个非递减有序顺序表A和B合并成一个新的非递减有序顺序表C。

输入格式
第一行:顺序表A的元素个数
第二行:顺序表A的各元素(非递减),用空格分开
第三行:顺序表B的元素个数
第四行:顺序表B的各元素(非递减),用空格分开

输出格式
第一行:顺序表A的元素列表
第二行:顺序表B的元素列表
第三行:合并后顺序表C的元素列表

输入样例
5
1 3 5 7 9
5
2 4 6 8 10

输出样例
List A:1 3 5 7 9
List B:2 4 6 8 10
List C:1 2 3 4 5 6 7 8 9 10

提示
输出时注意大小写和标点。

代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define OK 1
#define ERROR 0
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define ElemType int

typedef int Status;

typedef struct
{
	int *elem;
	int length;//实际长度
	int listsize;//存储容量,做检测用,避免长度超过容量
}SqList;

Status InitList_sq(SqList &L)
{
    L.elem=new ElemType[LIST_INIT_SIZE];//其实就是表示 数组
    if(!L.elem) return OK;
    L.length=0;
    L.listsize = LIST_INIT_SIZE;
    return OK;

}

Status ListInsert_Sq(SqList& L, int i, ElemType e)
{  // 算法2.4
  // 在顺序线性表L的第i个元素之前插入新的元素e,
  // i的合法值为1≤i≤ListLength_Sq(L)+1
	ElemType* p;
	if (i < 1 || i > L.length + 1) return ERROR;  // i值不合法


	if (L.length >= L.listsize) {   // 当前存储空间已满,增加容量
		ElemType* newbase = (ElemType*)realloc(L.elem,
			(L.listsize + LISTINCREMENT) * sizeof(ElemType));
		if (!newbase) return ERROR;   // 存储分配失败
		L.elem = newbase;             // 新基址
		L.listsize += LISTINCREMENT;  // 增加存储容量
	}


	ElemType* q = &(L.elem[i - 1]);   // q为插入位置
	for (p = &(L.elem[L.length - 1]); p >= q; --p) *(p + 1) = *p;
	// 插入位置及之后的元素右移
	*q = e;       // 插入e
	++L.length;   // 表长增1
	return OK;
} // ListInsert_Sq


Status ListDelete_Sq(SqList& L, int i, ElemType& e)
{  // 算法2.5
  // 在顺序线性表L中删除第i个元素,并用e返回其值。
  // i的合法值为1≤i≤ListLength_Sq(L)。
	ElemType* p, * q;
	if (i<1 || i>L.length) return ERROR;  // i值不合法
	p = &(L.elem[i - 1]);                   // p为被删除元素的位置
	e = *p;                               // 被删除元素的值赋给e

	q = L.elem + L.length - 1;                // 表尾元素的位置
	for (++p; p <= q; ++p) *(p - 1) = *p;     // 被删除元素之后的元素左移
	--L.length;                           // 表长减1
	return OK;
} // ListDelete_Sq

int main()
{
	SqList A, B, C;
	InitList_Sq(A);
	InitList_Sq(B);
	InitList_Sq(C);

	int a, b, c, each1, each2;
	scanf("%d", &a);
	for (int i = 0; i < a; i++) {
		scanf("%d", &each1);
		ListInsert_Sq(A, A.length + 1, each1);
	}
	printf("List A:");
	for (int i = 0; i < A.length; i++) {
		printf("%d ", A.elem[i]);
	}
	printf("\n");

	scanf("%d", &b);
	for (int j = 0; j < b; j++) {
		scanf("%d", &each2);
		ListInsert_Sq(B, B.length + 1, each2);
	}
	printf("List B:");
	for (int i = 0; i < B.length; i++) {
		printf("%d ", B.elem[i]);
	}
	printf("\n");



	int i = 0, j = 0;
	while (i < a && j < b) {
		if (A.elem[i] <= B.elem[j]) {
			ListInsert_Sq(C, C.length + 1, A.elem[i]);
			i++;//当前元素被使用,进入下一位
		}
		else {
			ListInsert_Sq(C, C.length + 1, B.elem[j]);
			j++;
		}
	}

	while (i < a) {//此时已不满足j < b
		ListInsert_Sq(C, C.length + 1, A.elem[i]);
		i++;
	}
	while (j < b) {
		ListInsert_Sq(C, C.length + 1, B.elem[j]);
		j++;
	}
	printf("List C:");
	for (int i = 0; i < C.length; i++) {
		printf("%d ", C.elem[i]);
	}
	printf("\n");
	return 0;
}

当你写到8578(即下一道题)时就会发现其实除主函数外的函数基本上都有提供。
因此作为基本函数理解算理也非常重要

要知道的几点:

  1. 顺序表和数组的区别与联系:
    (a)线性表采用顺序存储的方式存储就称之为顺序表,顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。而数组是从物理存贮的角度来说的,线性表可以用数组存贮也可以用链表来存贮。
    (b)可以用一种浅略的观点理解顺序表:带长度(和容量)的数组

  2. new 和 newbase
    (a)new操作符,即new函数仅仅是用来申请内存空间,不进行其他任何操作,而且针对对象是void*数据类型的指针
    (b)newbase:新基址

  3. 删除算法 和 插入算法 的算法原理
    (a)删除:删除第i项—> 被删除元素之后的元素左移 —> 表长减一
    (b)插入:i值和容量检测 —>找到插入位置—> 以后元素右移 —>插入表长加一

  4. q = L.elem + L.length - 1; 为啥表示表尾元素的位置?
    L.elem表示元素存放的首地址,总共是有L.length个元素,由于是最后一个元素,地址即为L.elem + L.length - 1

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
顺序是一种线性的存储结构,可以通过连续的存储空间来存储元素。当需要合并两个顺序时,需要将两个顺序中的元素按照一定的顺序合并到一个新的顺序中。 在合并过程中,在考虑元素顺序的基础上,还需要考虑两个顺序的大小关系。假设要合并两个顺序 A 和 B,其中 A 的长度为 m, B 的长度为 n,则合并后的顺序 C 的长度应该为 m+n。 具体的合并过程可以通过遍历两个顺序,逐个比较元素的大小,并将较小的元素添加到顺序 C 中。当其中一个顺序遍历完后,将另一个顺序的剩余元素直接添加到顺序 C 后面即可。 举个例子,假设合并前的顺序 A 中的元素为 [1, 2, 4, 6, 8],顺序 B 中的元素为 [3, 5, 7, 9]。初始时,顺序 C 为空。 在遍历的过程中,先比较 A 的第一个元素和 B 的第一个元素,发现 A 的第一个元素较小,将其添加到顺序 C 中。然后继续比较 A 的第二个元素和 B 的第一个元素,发现 B 的第一个元素较小,将其添加到顺序 C 中。接着比较 A 的第二个元素和 B 的第二个元素,发现 B 的第二个元素较小,将其添加到顺序 C 中。以此类推,直到遍历完 A 或者 B 中的元素。 最后,如果 A 中的元素已经全部添加到顺序 C 中,那么将 B 中剩余的元素直接添加到顺序 C 中。如果 B 中的元素已经全部添加到顺序 C 中,那么将 A 中剩余的元素直接添加到顺序 C 中。 最终,顺序 C 中的元素为 [1, 2, 3, 4, 5, 6, 7, 8, 9]。合并完成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值