C语言顺序表,含求合集,交集,原地倒置

C语言实现顺序表操作:初始化、插入、删除、查找、合并与交集
本文介绍了C语言实现顺序表的各种操作,包括初始化、插入元素、删除元素、查找元素、判断顺序表是否为空或已满、显示所有元素、倒置顺序表、合并两个线性表以及计算两个线性表的交集。示例代码详细展示了这些操作的实现细节。

C语言顺序表

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define maxsize 100
#define ERROR -1
#define OK 1

typedef struct List {
	int* Elem;
	int length;
}List;

//初始化顺序表
int initList(List* L) {
	L->Elem = (int*)malloc(sizeof(int) * maxsize);
	if (!L->Elem) {
		return ERROR;
	}
	L->length = 0;
	return OK;
}

//销毁顺序表
void destroy(List* L) {
	if (L->Elem)
	{
		free(L->Elem);
		L->Elem = NULL;
		L->length = 0;
	}
}



//追加元素到线性表的表尾
bool append(List* L, int e) {
	//进行插入前的判断
	if (!L->Elem || L->length < maxsize - 1)
	{
		L->Elem[L->length++] = e;
		return true;
	}
	else
	{
		return false;
	}
}



//插入元素,在第i个位置之前插入元素e
bool insert(List* L, int i, int e) {
	//进行插入前的判断
	if (L->Elem && L->length >= maxsize)
	{
		return ERROR;
	}
	//需要先将数组中第i位置之后的所有元素都统一向后移动一位
	for (int j = L->length; j > i; j--)
	{
		L->Elem[j] = L->Elem[j - 1];
	}
	L->length++;
	L->Elem[i] = e;
	return OK;
}



//删除元素,删除数组中第i位置的元素,并将其值返回
bool delete(List* L, int i, int* e) {
	//进行删除前的判断
	if (!L->Elem || i < 0 || i >= L->length) {
		return false;
	}
	//需要将第i位置的元素保存起来,然后使i之后的元素向前移动一位
	*e = L->Elem[i];
	for (int j = i; j < L->length - 1; j++)
	{
		L->Elem[j] = L->Elem[j + 1];
	}
	L->length--;
	return true;
}



//查找顺序表中是否存在元素e,如果存在返回第一个与之相等的元素的下标,如果没有,则返回-1;
int getIndex(List* L, int e) {
	//进行查询前的判断
	if (L->Elem && L->length > 0)
	{
		for (int i = 0; i < L->length; i++)
		{
			if (L->Elem[i] == e)
			{
				return i;
			}
		}
	}
	return -1;
}



//判断顺序表是否为空
bool isEmpty(List* L) {
	if (L->Elem && L->length == 0)
	{
		return OK;
	}
	return false;
}



//判断顺序表是否为满
bool isFull(List* L) {
	if (L->Elem && L->length == maxsize)
	{
		return OK;
	}
	return false;
}



//输出所有元素
void show(List* L) {
	if (L->Elem && L->length > 0)
	{
		for (int i = 0; i < L->length; i++)
		{
			printf("顺序表中第%d个元素是%d\n", i, L->Elem[i]);
		}
	}
}

//排序

//倒置顺序表
void inversion(List* L) {
	if (L->Elem && L->length > 0) {
		int temp;
		for (int i = 0; i < L->length / 2; i++)
		{
			temp = L->Elem[i];
			L->Elem[i] = L->Elem[L->length - 1 - i];
			L->Elem[L->length - 1 - i] = temp;
		}
	}
	else
	{
		return ERROR;
	}
}

//合并两个线性表,将顺序表 A 与 顺序表 B 合并,存于 A 中
void merge(List* A, List* B) {

	//这里省去对A,B表的判断,并默认A中可以存放A和B中所有的元素
	//在将B中元素添加到A的过程中,需要判断A中是否已经存在了B中的元素
	for (size_t i = 0; i < B->length; i++)
	{
		int flag = getIndex(A, B->Elem[i]);
		if (flag == -1) {
			A->Elem[A->length++] = B->Elem[i];
		}
	}
}

//两个线性表的交集,排序 + 双指针
//此方法是一个compare方法,正序
int cmp(void* a, void* b) {
	return *(int*)a - *(int*)b;
}
void intersection(List* a, List* b, List* returnC) {
	
	qsort(a->Elem, a->length, sizeof(a->Elem[0]), cmp);
	qsort(b->Elem, b->length, sizeof(a->Elem[0]), cmp);
	
	int minLength = a->length - b->length < 0 ? a->length : b->length;
	
	returnC->Elem = (int*)malloc(sizeof(int) * minLength);
	returnC->length = 0;
	
	int index1 = 0;
	int index2 = 0;
	while (index1 < a->length && index2 < b->length)
	{
		if (a->Elem[index1] == b->Elem[index2])
		{
			append(returnC, a->Elem[index1]);
			index1++;
			index2++;
		}
		else if (a->Elem[index1] > b->Elem[index2])
		{
			index2++;
		}
		else
		{
			index1++;
		}
	}
}

int main() {
	List L;
	initList(&L);
	for (int i = 0; i < 10; i++)
	{
		append(&L, i);	
	}
	insert(&L, (&L)->length - 1, -1);
	show(&L);
	
	//测试删除
	printf("测试删除=====\n");
	int del = -1;
	delete(&L, 3, &del);
	show(&L);
	printf("删除的元素是%d\n", del);
	printf("获取元素 %d 下标 %d\n",5, getIndex(&L, 5));
	printf("获取元素 %d 下标 %d\n",99, getIndex(&L, 99));
	destroy(&L);

	//测试合并
	printf("测试合并=========\n");
	List a; 
	List b;
	initList(&a);
	initList(&b);
	for (int i = 0; i < 10; i++)
	{
		append(&a, i);
		append(&b, i+9);
	}
	show(&a);
	show(&b);
	printf("合并====start\n");
	merge(&a, &b);
	show(&a);
	printf("合并====end\n");
	destroy(&a);
	destroy(&b);

	//测试顺序表的交集
	printf("测试顺序表的交集\n");
	List c, d, returnc;
	initList(&c);
	initList(&d);
	for (int i = 0; i < 10; i++)
	{
		append(&c, i);
		append(&d, i+8);
	}
	show(&c);
	show(&d);

	printf("======start\n");
	intersection(&c, &d, &returnc);
	printf("======end\n");

	show(&returnc);

	destroy(&c);
	destroy(&d);

	//测试顺序表倒置
	printf("测试顺序表倒置===========start\n");
	List e;
	initList(&e);
	for (int i = 0; i < 9; i++)
	{
		append(&e, i);
	}
	show(&e);
	inversion(&e);
	show(&e);
	printf("测试顺序表倒置===========end\n");
	destroy(&e);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值