顺序表

动态顺序表

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#define InitSize 10//默认最大长度
#define NULLVal INT_MIN;
typedef int ElemType;

typedef struct {
	ElemType *data;//指示动态分配数组的指针
	int length;//顺序表的最大容量
	int MaxSize;//顺序表的当前长度
}SqList;

//初始化顺序表
bool InitList(SqList& L) {
	//用malloc函数申请一片连续的存储空间
	L.data = (ElemType*)malloc(sizeof(ElemType) * InitSize);
	if (L.data == NULL) {
		return false;
	}
	L.length = 0;
	L.MaxSize = InitSize;
	return true;
}

//增加动态数组长度
void IncreaseSize(SqList& L, int len) {
	ElemType* p = L.data;
	L.data = (ElemType *)malloc(sizeof(ElemType) * (InitSize+len));
	for (int i = 0; i < L.length; i++) {
		L.data[i] = p[i];//将数据复制到新区域
	}
	L.MaxSize = L.MaxSize + len;//顺序表最大长度增加len
	free(p);//释放原来的内存空间
}


//顺序表插入 时间复杂度:O(n)
bool ListInsert(SqList& L, int i, ElemType e) {
	if (i <= 0 || i > L.length + 1) {//判断i的范围是否有效
		return false;
	}
	if (L.length >= L.MaxSize) {//当前存储空间已满,不能插入
		return false;
	}
	for (int j = L.length; j >= i; j--) {//第i个元素之后的元素后移
		L.data[j] = L.data[j - 1];
	}
	L.data[i - 1] = e;//在位置插入
	L.length++;//长度加1
	return true;
}

//顺序表的删除 时间复杂度O(n)
bool ListDelete(SqList& L, int i, ElemType& e) {
	if (i <= 0 || i > L.length) {//判断i的范围是否有效
		return false;
	}
	e = L.data[i - 1];//将被删除的元素赋值给e
	for (int j = i; j < L.length; j++) {//将第i个位置后的元素前移
		L.data[j - 1] = L.data[j];
	}
	L.data[L.length - 1] = 0;
	L.length--;//线性表长度减一
	return true;
}


//顺序表的按位查找 时间复杂度O(1)
ElemType GetElem(SqList L, int i) {
	if (i <= 0 || i > L.length) {
		return NULLVal;
	}
	return L.data[i - 1];
}

//顺序表的按值查找 时间复杂度O(n)
int LocateElem(SqList L, int e) {
	for (int i = 0; i < L.length; i++) {
		if (L.data[i] == e) {//如果数据类型为结构体类型,需比较结构体内的元素相等
			return i + 1;//数组下标为i的元素值等于e,返回其位序i+1
		}
	}
	return 0; //退出循环,说明查找失败
}

//判断顺序表是否为空
bool ListEmpty(SqList L) {
	return L.length == 0;
}

//创建
bool ListCreate(SqList& L) {
	int  n;
	printf("请输入创建数据的个数:");
	scanf("%d", &n);
	//printf("\n");
	for (int i = 1; i <= n; i++) {
		ElemType e;
		printf("请输入第%d个数据:", i);
		scanf("%d", &e);
		//printf("\n");
		bool b = ListInsert(L, i, e);
		if (b == false)
			printf("插入失败\n");
	}
	return true;
}

//打印
void PrintList(SqList L) {
	for (int i = 0; i < L.length; i++) {
		printf("%5d", L.data[i]);
	}
	printf("\n");
}

//销毁
bool DestroyList(SqList& L) {
	free(L.data);
	L.length = 0;
	L.MaxSize = 0;
	return true;
}
int main() {
	SqList L;//声明一个顺序表
	InitList(L);//初始化顺序表
	//数据的插入
	ListCreate(L);//创建顺序表
	printf("%d\n", L.length);
	//数据的位置
	int i = LocateElem(L, 5);
	printf("查找的数字位置是%d\n", i);
	//数据的值
	ElemType e = GetElem(L, 3);
	printf("查找的位置数字是%d\n", e);
	//数据的删除
	ListDelete(L, 1, e);
	printf("删除的值是%d,删除后的长度为%d\n", e, L.length);
	//顺序打印
	PrintList(L);
	//顺序表销毁
	DestroyList(L);
	//判断顺序表是否为空
	if (ListEmpty(L) == true) {
		printf("顺序表为空\n");
	}
	else {
		printf("顺序表不为空\n");
	}
	return 0;
}

静态顺序表

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define NULLVal INT_MIN;
#define MaxSize 100//定义最大长度
typedef int ElemType;

typedef struct {
	ElemType data[MaxSize];//用静态的"数组"存储数据元素
	int length;//顺序表
	int maxsize;
}SqList;//顺序表的类型定义

//初始化静态顺序表
bool InitList(SqList& L) {
	for (int i = 0; i < MaxSize; i++) {
		L.data[i] = 0;//将所有元素设为默认初始值
	}
	L.length = 0;//顺序表初始长度为0
	L.maxsize = MaxSize;
	return true;
}

//顺序表插入 时间复杂度:O(n)
bool ListInsert(SqList& L, int i, ElemType e) {
	if (i <= 0 || i > L.length+1) {//判断i的范围是否有效
		return false;
	}
	if (L.length >= MaxSize) {//当前存储空间已满,不能插入
		return false;
	}
	for (int j = L.length; j >= i; j--) {//第i个元素之后的元素后移
		L.data[j] = L.data[j - 1];
	}
	L.data[i - 1] = e;//在位置插入
	L.length++;//长度加1
	return true;
}

//顺序表的删除 时间复杂度O(n)
bool ListDelete(SqList& L, int i, ElemType& e) {
	if (i <= 0 || i > L.length) {//判断i的范围是否有效
		return false;
	}
	e = L.data[i - 1];//将被删除的元素赋值给e
	for (int j = i; j < L.length; j++) {//将第i个位置后的元素前移
		L.data[j-1] = L.data[j];
	}
	L.data[L.length - 1] = 0;
	L.length--;//线性表长度减一
	return true;
}


//顺序表的按位查找 时间复杂度O(1)
ElemType GetElem(SqList L, int i) {
	if (i <= 0 || i > L.length) {
		return NULLVal;
	}
	return L.data[i - 1];
}

//顺序表的按值查找 时间复杂度O(n)
int LocateElem(SqList L, int e) {
	for (int i = 0; i < L.length; i++) {
		if (L.data[i] == e) {//如果数据类型为结构体类型,需比较结构体内的元素相等
			return i+1;//数组下标为i的元素值等于e,返回其位序i+1
		}
	}
	return 0; //退出循环,说明查找失败
}

//判断顺序表是否为空
bool ListEmpty(SqList L) {
	return L.length == 0;
}

//顺序表的创建
bool ListCreate(SqList& L) {
	int  n;//元素个数
	printf("请输入创建数据的个数:");
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		ElemType e;//元素值
		printf("请输入第%d个数据:", i);
		scanf("%d", &e);
		bool b = ListInsert(L, i, e);//后插法
		if (b == false)//是否插入成功
		printf("插入失败\n");
	}
	return true;
}

//顺序表顺序打印
void PrintList(SqList L) {
	for (int i = 0; i < L.length; i++) {
		printf("%5d", L.data[i]);
	}
	printf("\n");
}

提升

//扩展提升
//删除顺序表中最小元素,并由函数返回被删元素,空出的位置由最后一个元素填充
bool Del_Min(SqList &L, ElemType& e) {
	if (L.length == 0) {
		return false;
	}
	e = L.data[0];
	int pos = 0;
	for (int i = 1; i < L.length; i++) {
		if (L.data[i] < e) {
			e = L.data[i];
			pos = i;
		}
	}
	L.data[pos] = L.data[L.length - 1];
	L.length--;
	return true;
}

//元素逆置
void Reverse(SqList& L) {
	//交换前后对称位置的值
	for (int i = 0; i < L.length/2; i++) {
		ElemType temp = L.data[i];
		L.data[i] = L.data[L.length - i - 1];
		L.data[L.length - i - 1] = temp;
	}
}

//删除所有值为x的元素,时间复杂度O(n),空间复杂度O(1)
//方法一
void Del_x_1(SqList& L, ElemType x) {
	int k = 0;//记录值等于x的元素个数
	for (int i = 0; i < L.length; i++) {
		if (L.data[i] == x) {
			k++;
		}
		else {
			L.data[i - k] = L.data[i];//当前元素前移k个位置
		}
	}
	L.length -= k;//顺序表L的长度减少k个
}
//方法二
void Del_x_2(SqList& L, ElemType x) {
	int k = 0;//记录值不等于x的元素个数
	for (int i = 0; i < L.length; i++) {
		if (L.data[i] != x) {
			L.data[k] = L.data[i];
			k++;//不等于x的元素增一
		}
	}
	L.length = k;//顺序表长度等于k
}

//删除顺序表元素值在s与t之间的所有元素,包含s和t
bool Del_s_t1(SqList& L, ElemType s, ElemType t) {
	if (s >= t || L.length == 0) {//线性表为空,s或t不符合,返回
		return false;
	}
	int k = 0;
	for (int i = 0; i < L.length; i++) {
		if (L.data[i] < s|| L.data[i] > t) {
			L.data[k] = L.data[i];//当前元素前移k个位置
			k++;
		}
	}
	L.length = k;//长度减小
	return true;
}

//删除有序顺序表元素值在s与t之间,包含s和t
bool Del_s_t2(SqList& L, ElemType s, ElemType t) {
	if (s >= t || L.length == 0) {
		return false;
	}
	int i = 0;
	for (; i < L.length && s > L.data[i]; i++);//寻找大于等于s的第一个元素
	if (i >= L.length) {
		return false;//所有值均小于s,返回
	}
	int j = i;
	for (; j < L.length && t >= L.data[j]; j++);//寻找大于t的第一个元素
	for (; j < L.length; i++, j++) {
		L.data[i] = L.data[j];//前移,填补被删元素的位置
	}
	L.length = i;
	return true;
}

//从有序表中删除值重复的元素,使表中所有元素均不同
bool Del_Same(SqList& L) {
	if (L.length == 0) {
		return false;
	}
	int k = 0;//k存储第一个不相同元素位置
	for (int i = 1; i < L.length; i++) {
		if (L.data[i] != L.data[k]) {//查找下一个与上一个元素值不同的元素
			L.data[++k] = L.data[i];//找到后将元素前移
		}
	}
	L.length = k+1;
	return true;
}

//将两个有序表合并为一个有序表
bool Merge(SqList L1, SqList L2, SqList& L3) {
	if (L1.length + L2.length > L3.maxsize) {
		return false;
	}
	int i = 0, j = 0, k = 0;
	while (i < L1.length || j < L2.length) {
		if (i >= L1.length) {//当L1遍历完,只需存储L2的剩余元素
			L3.data[k++] = L2.data[j++];
		}
		else if (j >= L1.length) {//当L2遍历完,只需存储L1的剩余元素
			L3.data[k++] = L2.data[i++];
		}
		else if (L1.data[i] <= L2.data[j]) {//当L1比L2小,存储L1的当前元素
			L3.data[k++] = L1.data[i++];
		}
		else {//当L2比L1小,存储L2的当前元素
			L3.data[k++] = L2.data[j++];
		}
	}
	L3.length = k;
	return true;
}

//将顺序表[M+N]切分为两部分A和B,将AB调换位置,变为BA,如{a1,a2,a3,a4,a5},A={a1,a2},B={a3,a4,a5},调换为{a3,a4,a5,a1,a2}
void reverse(SqList& L, int left, int right) {
	while (left < right) {
		ElemType temp = L.data[left];
		L.data[left] = L.data[right];
		L.data[right] = temp;
		left++;
		right--;
	}
}

void Exchange(SqList& L, int m, int n) {
	if (m<0||n<0||m + n > L.length) {
		return;
	}
	reverse(L, 0, m + n - 1);
	reverse(L, 0, m - 1);
	reverse(L, m, m + n - 1);
}

//用最少时间查找有序顺序表值为x的元素,若存在与其后继元素交换位置,不存在则将其插入表中,是顺序表依然有序
void SearchExchangeInsert(SqList& L, ElemType x) {
	int left = 0, right = L.length - 1, mid;
	while (left <= right) {//二分查找
		mid = (left + right) / 2;
		if (L.data[mid] == x) {
			break;
		}
		else if (L.data[mid] < x) {
			left = mid + 1;
		}
		else {
			right = mid - 1;
		}
	}
	if (mid!=L.length-1&&L.data[mid] == x) {//位置调换
		ElemType temp = L.data[mid];
		L.data[mid] = L.data[mid + 1];
		L.data[mid + 1] = temp;
	}
	if(left>right){
		for (int i = L.length; i > right; i--) {//插入元素
			L.data[i] = L.data[i - 1];
		}
		L.data[mid] = x;
		L.length++;
	}
}

//找数组中未出现的最小正数
int findMissMin(int A[], int n) {
	int *B = (int *)malloc(sizeof(int) * n);
	memset(B, 0, sizeof(int) * n);
	for (int i = 0; i < n; i++) {
		if (A[i] >= 1 && A[i] <= n) {
			B[A[i]-1] = 1;
		}
	}
	int i;
	for (i = 0; i < n; i++) {
		if (B[i] == 0)
			break;
	}
	return i+1;
}

//找非负整数数组中的主元素,主元素:出现次数超过数组长度一半的数,找到返回该数,找不到返回-1
//方法一:hash
//例[1,2,1,1]主元素为1,例[1,2,1,2]无主元素
//时间复杂度O(n),空间复杂度O(n)
int findMainElem(int A[], int n){
	int *hash = (int *)malloc(sizeof(int)*n);
	for(int i = 0; i < n; i++){
		hash[i] = 0;
	}
	for(int i = 0; i < n; i++){
		hash[A[i]]++;
		if(hash[A[i]] > n/2){
			return A[i];
		}
	}
	return -1;
}

//方法二
//时间复杂度O(n),空间复杂度O(1)
int findMainElem(int A[], int n){
	int count = 0, mainElem;
	for(int  i = 0; i < n; i++){
		if(count==0 || mainElem == A[i]){
			mainElem = A[i];
			count++;
		}else{
			count--;
		}
	}
	if(count == 0){
		return -1;	
	}
	count = 0;
	for(int i = 0; i < n; i++){
		if(A[i] == mainElem){
			count++;
		}
	}
	if(count >n/2){
		return mainElem;
	}else{
		return -1;
	}
}


int main() {
	SqList L;//声明一个顺序表
	InitList(L);//初始化顺序表
	//数据的插入
	ListCreate(L);//创建顺序表
	printf("%d\n", L.length);
	数据的位置
	//int i = LocateElem(L, 5);
	//printf("查找的数字位置是%d\n", i);
	数据的值
	//ElemType e = GetElem(L, 3);
	//printf("查找的位置数字是%d\n", e);
	数据的删除
	//ListDelete(L,1,e);
	//printf("删除的值是%d,删除后的长度为%d\n", e,L.length);
	判断顺序表是否为空

	删除最小值
	//ElemType e;
	//Del_Min(L, e);
	//printf("删除的最小值是%d\n", e);
	//printf("长度%d\n", L.length);

	逆置元素
	//Reverse(L);
	//PrintList(L);

	删除值为x的元素
	//Del_x_1(L, 5);
	//PrintList(L);
	//printf("长度%d\n", L.length);
	//Del_x_2(L, 2);
	//PrintList(L);
	//printf("长度%d\n", L.length);
	
	//删除s和t之间的元素
	/*Del_s_t2(L, 2, 5);
	PrintList(L);
	printf("长度%d\n", L.length);*/

	//删除重复元素
	/*Del_Same(L);
	PrintList(L);
	printf("长度%d\n", L.length);*/

	//合并有序表
	/*SqList L3;
	InitList(L3);
	Merge(L, L, L3);
	PrintList(L3);
	printf("长度%d\n", L3.length);*/

	//交换顺序表
	/*Exchange(L, 2, 3);
	PrintList(L);
	printf("长度%d\n", L.length);*/

	//查找交换插入元素
	for (int i = 0; i < 5; i++) {
		ElemType x;
		printf("输入插入的数据:");
		scanf("%d", &x);
		SearchExchangeInsert(L, x);
		PrintList(L);
		printf("长度%d\n", L.length);
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Baal Austin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值