一、2.1 求并集, P20页:(代码可直接运行)
我们知道顺序表是基于数组实现的,而数组本身有静态存储和动态存储两种实现方式,所以本次代码将分别实现静态数组和动态数组的并集运算
题目描述 : 两个线性表LA和LB分别表示集合A和B,求 A = A + B (A并B)
思路:课本伪代码
void union(List &La, List Lb)
{
// 将所有在线性表Lb中但不在La中的数据元素插入到La中
La_len = ListLength(La); Lb_len = ListLength(Lb); // 求线性表的长度
for (i = 1; i <= Lb_len; i ++ )
{
GetElem(Lb, i, e); // 取Lb中第i个数据元素赋给e
if (!LocateElem(La, e, equal)) ListInsert(La, ++La_len, e);
// La中不存在和e相同的数据元素,则插入之
}
} // union
✨二、注意要点总结
- 顺序表的两种实现方式 : 静态数组和动态数组
- sizeof() 在C语言中是一个内置的运算符, 而不是函数,用于判断变量或表达式的长度(以字节为单位)。
// sizeof的语法形式 1. sizeof (类型说明符) 2. sizeof 表达式 // 此时加不加括号都可以, 所以可以直接都加() 注意:类型说明符和表达式不可混用 如 :当计算10个int类型的大小时 : sizeof (int) * 10, 而不是sizeof (int * 10)
这种错误大概率会出现在malloc的时候, 我就错了,QAQ,这还是第二次,之前还错过一次了,😓
-
比如 : 要开辟10个int 类型 要写成 : (...)malloc (sizeof(int) * 10) 而不是跟我错的一样, 写成sizeof (int * 10), QAQ 这个时候 会报错
三、代码实现
1. 静态数组
// 法一 : 顺序表的静态存储实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define LIST_INIT_SIZE 100 // 线性表存储空间的初始分配量
#define LISTINCREMENT 10 // 线性表存储空间的分配增量
// 顺序表的静态存储结构
typedef struct List
{
int elems[LIST_INIT_SIZE];
int length; // 当前长度
int listsize; // 当前分配的存储容量
} List;
// 初始化顺序表
List* ListInit(void)
{
List *A = (List*)malloc(sizeof(List));
A->length = 0;
A->listsize = LIST_INIT_SIZE;
return A;
}
// 求顺序表的长度
int ListLength(List *A)
{
return A->length;
}
// 将表中第i个元素赋值给e
bool GetElem(List *A, int i, int *e)
{
*e = A->elems[i];
return true;
}
// 找表中是否有和e相同的元素, 并将下标值赋给equal
bool LocateElem(List *A, int e, int *equal)
{
for (int i = 0; i < A->length; i ++ )
{
if (A->elems[i] == e)
{
*equal = i;
return true;
}
}
return false;
}
// 将元素插入表中
bool ListInsert(List *A, int e)
{
A->elems[A->length ++] = e;
return true;
}
int main()
{
char *a = (char*)malloc(sizeof(LIST_INIT_SIZE + LISTINCREMENT)); // 注意指针的使用,不malloc会指向NULL, 不可赋值,会报错:EXC_BAD_ACCESS (code=1, address=0x0)
char *b = (char*)malloc(sizeof(LIST_INIT_SIZE + LISTINCREMENT));
List *A = ListInit();
List* B = ListInit();
scanf("%s %s", a, b); // 读入集合,以字符串形式读入, 转化成整数存入顺序表中
for (int i = 0; i < strlen(a); i ++ ) ListInsert(A, a[i] - '0');
for (int i = 0; i < strlen(b); i ++ ) ListInsert(B, b[i] - '0');
for (int i = 0; i < A->length; i ++ )
{
int *equal = (int*)malloc(sizeof(int));
for (int j = 0; j < B->length; j ++ )
if (LocateElem(A, B->elems[j], equal))
continue;
else ListInsert(A, B->elems[j]);
}
for (int i = 0; i < A->length; i ++ ) printf("%d", A->elems[i]);
printf("\n");
return 0;
}
2. 动态数组 (其实变化只是在创建和初始化列表的时候,对数组的处理)
// 法二: 顺序表的动态数组实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
// 顺序表的静态存储结构
typedef struct List
{
int *elems; // 找不同~
int length;
int listsize;
} List;
// 初始化顺序表
List* ListInit(void)
{
List *A = (List*)malloc(sizeof(List));
A->elems = (int*)malloc(sizeof(int)* LIST_INIT_SIZE); // 找不同
A->length = 0;
A->listsize = LIST_INIT_SIZE;
return A;
}
// 求顺序表的长度
int ListLength(List *A)
{
return A->length;
}
// 将表中第i个元素赋值给e
bool GetElem(List *A, int i, int *e)
{
*e = A->elems[i];
return true;
}
// 找表中是否有和e相同的元素, 并将下标值赋给equal
bool LocateElem(List *A, int e, int *equal)
{
for (int i = 0; i < A->length; i ++ )
{
if (A->elems[i] == e)
{
*equal = i;
return true;
}
}
return false;
}
// 将元素插入表中
bool ListInsert(List *A, int e)
{
A->elems[A->length ++] = e;
return true;
}
int main()
{
char *a = (char*)malloc(sizeof(LIST_INIT_SIZE + 10));
char *b = (char*)malloc(sizeof(LIST_INIT_SIZE + 10));
List *A = ListInit();
List* B = ListInit();
scanf("%s %s", a, b);
for (int i = 0; i < strlen(a); i ++ ) ListInsert(A, a[i] - '0');
for (int i = 0; i < strlen(b); i ++ ) ListInsert(B, b[i] - '0');
for (int i = 0; i < A->length; i ++ )
{
int *equal = (int*)malloc(sizeof(int));
for (int j = 0; j < B->length; j ++ )
if (LocateElem(A, B->elems[j], equal))
continue;
else ListInsert(A, B->elems[j]);
}
for (int i = 0; i < A->length; i ++ ) printf("%d", A->elems[i]);
printf("\n");
return 0;
}