数据结构之静态顺序表和动态顺序表

@Sock对静态顺序表和动态顺序表的总结

简单概括他们的异同点

相同点:内存空间连续, 数据顺序存储

不同点:它们所占内存空间的位置不同, 静态定义一个顺序表, 顺序表所占的内存空间开辟在内存的静态区, 即所谓的函数栈上, 随着函数调用的结束, 这块内存区域会被系统自动回收; 而动态生成一个顺序表, 顺序表所占的内存空间开辟在内存的动态区, 即所谓的堆内存上, 这块区域不会随着函数调用的结束被系统自动回收, 而是需要程序员主动去释放它.

各自优点(个人认为)

静态顺序表:操作简单, 不用手动释放其内存空间, 不存在内存泄漏

动态顺序表:可以动态开辟内存空间, 操作灵活, 避免不必要的开销

静态顺序表的实现

定义一个静态顺序表

//定义一个静态顺序表
#define MAXSIZE 100
typedef int ElemType;
ElemType SqList[MAXSIZE];
int len;

向静态顺序表中插入元素

//向静态顺序表中插入元素
void InsertElem(ElemType* S, int* len, int pos, ElemType e) {
	//判断插入位置是否合理
	if (*len == MAXSIZE || pos < 1 || pos > *len + 1) {
		printf("表满或插入位置不合理\n");
		exit(0);
	}
	//调整插入位置, 准备插入指定元素
	for (int i = *len - 1; i >= pos - 1; --i) {
		*(S + i + 1) = *(S + i);
	}
	//插入指定元素
	*(S + pos - 1) = e;
	//元素个数加 1
	++(*len);
}

从静态顺序表中删除元素

//向静态顺序表中删除元素
void DelElem(ElemType* S, int* len, int pos) {
	//判断删除位置是否合理
	if (pos < 1 || pos > *len) {
		printf("删除位置不合理\n");
		exit(0);
	}
	//调整删除位置, 准备删除指定元素
	for (int i = pos; i < *len; ++i) {
		*(S + i - 1) = *(S + i);
	}
	//元素个数减 1
	--(*len);
}

遍历静态顺序表

//遍历顺序表
void Traverse(ElemType* S) {
	for (int i = 0; i < len; ++i) {
		printf("%d ", *(S + i));
	}
	printf("\n");
}

测试

#include 
#include 

//定义一个静态顺序表
#define MAXSIZE 100
typedef int ElemType;
ElemType SqList[MAXSIZE];
int len;

//向静态顺序表中插入元素
void InsertElem(ElemType* S, int* len, int pos, ElemType e) {
	//判断插入位置是否合理
	if (*len == MAXSIZE || pos < 1 || pos > *len + 1) {
		printf("表满或插入位置不合理\n");
		exit(0);
	}
	//调整插入位置, 准备插入指定元素
	for (int i = *len - 1; i >= pos - 1; --i) {
		*(S + i + 1) = *(S + i);
	}
	//插入指定元素
	*(S + pos - 1) = e;
	//元素个数加 1
	++(*len);
}

//向静态顺序表中删除元素
void DelElem(ElemType* S, int* len, int pos) {
	//判断删除位置是否合理
	if (pos < 1 || pos > *len) {
		printf("删除位置不合理\n");
		exit(0);
	}
	//调整删除位置, 准备删除指定元素
	for (int i = pos; i < *len; ++i) {
		*(S + i - 1) = *(S + i);
	}
	//元素个数减 1
	--(*len);
}

//遍历顺序表
void Traverse(ElemType* S) {
	for (int i = 0; i < len; ++i) {
		printf("%d ", *(S + i));
	}
	printf("\n");
}

int main() {
	len = 5;
	for (int i = 0; i < len; ++i) {
		*(SqList + i) = i + 1;
	}
	Traverse(SqList);
	InsertElem(SqList, &len, 4, 100);
	Traverse(SqList);
	DelElem(SqList, &len, 4);
	Traverse(SqList);
	system("pause");
	return 0;
}

效果图
数据结构之静态顺序表和动态顺序表_第1张图片

动态顺序表的实现

定义一个动态顺序表

//定义一个动态顺序表
#define MAXSIZE 100
#define LISTINCREMENT 10
typedef int ElemType;
typedef struct SqList {
	ElemType* elem;
	int len;
	int listsize;
}SqList;

初始化

//初始化一个动态顺序表
void InitList(SqList* S) {
	//动态生成了一个指定大小的顺序表
	S->elem = (ElemType*)malloc(MAXSIZE * sizeof(ElemType));
	if (!S->elem) {
		printf("创建失败\n");
		exit(0);
	}
	S->len = 0;
	S->listsize = MAXSIZE;
}

向动态顺序表中插入元素

//向动态顺序表中插入元素
void InsertElem(SqList* S, int pos, ElemType e) {
	//判断插入位置是否合理
	if (pos < 1 || pos > S->len + 1) {
		printf("插入位置不合理\n");
		return;// exit(0);
	}
	//判断表是否为满
	if (S->len == S->listsize) {
		SqList q;
		q.elem = (ElemType*)realloc(S->elem, (S->listsize + LISTINCREMENT) * sizeof(ElemType));
		if (!q.elem) {
			exit(0);
		}
		S->elem = q.elem;
		S->listsize += LISTINCREMENT;
	}
	//调整插入位置, 准备插入指定元素
	for (int i = S->len - 1; i >= pos - 1; --i) {
		*(S->elem + i + 1) = *(S->elem + i);
	}
	//插入指定元素
	*(S->elem + pos - 1) = e;
	//元素个数加 1
	++S->len;
}

从动态顺序表中删除元素

//从动态顺序表中删除元素
void DelElem(SqList* S, int pos) {
	//判断删除位置是否合理
	if (pos < 1 || pos > S->len) {
		printf("删除位置不合理\n");
		return;// exit(0);
	}
	//调整删除位置, 准备删除指定元素
	for (int i = pos; i < S->len; ++i) {
		*(S->elem + i - 1) = *(S->elem + i);
	}
	//元素个数减 1
	--S->len;
}

遍历动态顺序表

//遍历顺序表
void Traverse(SqList S) {
	for (int i = 0; i < S.len; ++i) {
		printf("%d ", *(S.elem + i));
	}
	printf("\n");
}

销毁一个动态顺序表

//销毁一个动态顺序表
void DestroyList(SqList* S) {
	//释放堆内存
	free(S->elem);
	S->elem = NULL;
	S->len = 0;
	S->listsize = 0;
	printf("销毁成功\n");
}

清空一个动态顺序表

//清空一个动态顺序表
void ClearList(SqList* S) {
	//令元素个数为 0
	S->len = 0;
	printf("已清空\n");
}

判断动态顺序表是否为空

//判断动态顺序表是否为空
int IsEmpty(SqList S) {
	if (S.len == 0) {
		//printf("表为空\n");
		return 1;
	}
	//printf("表不为空\n");
	return 0;
}

获取动态顺序表上指定位置的值

//获取动态顺序表上某个位置上的值
int GetElem(SqList S, int pos) {
	//判断获取位置是否合理
	if (pos < 1 || pos > S.len) {
		printf("获取位置不合理\n");
		return 0;// exit(0);
	}
	return *(S.elem + pos - 1);
}

在动态顺序表中查找指定值

//在动态顺序表中查找指定值
void LocateElem(SqList S, ElemType e) {
	//遍历顺序表
	for (int i = 0; i < S.len; ++i) {
		if (*(S.elem + i) == e) {
			printf("找到了该元素, 它是第 %d 个元素\n", i + 1);
			return;
		}
	}
	printf("没有找到该元素\n");
}

在动态顺序表中查找指定元素的前驱

//在动态顺序表中找某个元素的前驱
ElemType ProriElem(SqList S, ElemType cur_e) {
	//判断是否为第一个元素
	if (*S.elem == cur_e) {
		printf("第一个元素没有前驱\n");
		return 0;
	}
	//从第二个元素开始查找
	for (int i = 1; i < S.len; ++i) {
		if (*(S.elem + i) == cur_e) {
			//返回该元素的前驱
			return *(S.elem + i - 1);
		}
	}
	printf("没有该元素\n");
	return 0;
}

在动态顺序表中查找指定元素的后继

//在动态顺序表中找某个元素的后继
ElemType NextElem(SqList S, ElemType cur_e) {
	//判断是否为最后一个元素
	if (*(S.elem + S.len - 1) == cur_e) {
		printf("最后一个元素没后继\n");
		return 0;
	}
	//从头一直查到倒数第 2 个元素
	for (int i = 0; i < S.len - 1; ++i) {
		if (*(S.elem + i) == cur_e) {
			//返回该元素的后继	
			return *(S.elem + i + 1);
		}
	}
	printf("没有该元素\n");
	return 0;
}

测试

#include 
#include 

//定义一个动态顺序表
#define MAXSIZE 100
#define LISTINCREMENT 10
typedef int ElemType;
typedef struct SqList {
	ElemType* elem;
	int len;
	int listsize;
}SqList;

//初始化一个动态顺序表
void InitList(SqList* S) {
	//动态生成了一个指定大小的顺序表
	S->elem = (ElemType*)malloc(MAXSIZE * sizeof(ElemType));
	if (!S->elem) {
		printf("创建失败\n");
		exit(0);
	}
	S->len = 0;
	S->listsize = MAXSIZE;
}

//向动态顺序表中插入元素
void InsertElem(SqList* S, int pos, ElemType e) {
	//判断插入位置是否合理
	if (pos < 1 || pos > S->len + 1) {
		printf("插入位置不合理\n");
		return;// exit(0);
	}
	//判断表是否为满
	if (S->len == S->listsize) {
		SqList q;
		q.elem = (ElemType*)realloc(S->elem, (S->listsize + LISTINCREMENT) * sizeof(ElemType));
		if (!q.elem) {
			exit(0);
		}
		S->elem = q.elem;
		S->listsize += LISTINCREMENT;
	}
	//调整插入位置, 准备插入指定元素
	for (int i = S->len - 1; i >= pos - 1; --i) {
		*(S->elem + i + 1) = *(S->elem + i);
	}
	//插入指定元素
	*(S->elem + pos - 1) = e;
	//元素个数加 1
	++S->len;
}

//从动态顺序表中删除元素
void DelElem(SqList* S, int pos) {
	//判断删除位置是否合理
	if (pos < 1 || pos > S->len) {
		printf("删除位置不合理\n");
		return;// exit(0);
	}
	//调整删除位置, 准备删除指定元素
	for (int i = pos; i < S->len; ++i) {
		*(S->elem + i - 1) = *(S->elem + i);
	}
	//元素个数减 1
	--S->len;
}

//销毁一个动态顺序表
void DestroyList(SqList* S) {
	//释放堆内存
	free(S->elem);
	S->elem = NULL;
	S->len = 0;
	S->listsize = 0;
	printf("销毁成功\n");
}

//清空一个动态顺序表
void ClearList(SqList* S) {
	//令元素个数为 0
	S->len = 0;
	printf("已清空\n");
}

//判断动态顺序表是否为空
int IsEmpty(SqList S) {
	if (S.len == 0) {
		//printf("表为空\n");
		return 1;
	}
	//printf("表不为空\n");
	return 0;
}

//获取动态顺序表上某个位置上的值
int GetElem(SqList S, int pos) {
	//判断获取位置是否合理
	if (pos < 1 || pos > S.len) {
		printf("获取位置不合理\n");
		return 0;// exit(0);
	}
	return *(S.elem + pos - 1);
}

//在动态顺序表中查找指定值
void LocateElem(SqList S, ElemType e) {
	//遍历顺序表
	for (int i = 0; i < S.len; ++i) {
		if (*(S.elem + i) == e) {
			printf("找到了该元素, 它是第 %d 个元素\n", i + 1);
			return;
		}
	}
	printf("没有找到该元素\n");
}

//在动态顺序表中找某个元素的前驱
ElemType ProriElem(SqList S, ElemType cur_e) {
	//判断是否为第一个元素
	if (*S.elem == cur_e) {
		printf("第一个元素没有前驱\n");
		return 0;
	}
	//从第二个元素开始查找
	for (int i = 1; i < S.len; ++i) {
		if (*(S.elem + i) == cur_e) {
			//返回该元素的前驱
			return *(S.elem + i - 1);
		}
	}
	printf("没有该元素\n");
	return 0;
}

//在动态顺序表中找某个元素的后继
ElemType NextElem(SqList S, ElemType cur_e) {
	//判断是否为最后一个元素
	if (*(S.elem + S.len - 1) == cur_e) {
		printf("最后一个元素没后继\n");
		return 0;
	}
	//从头一直查到倒数第 2 个元素
	for (int i = 0; i < S.len - 1; ++i) {
		if (*(S.elem + i) == cur_e) {
			//返回该元素的后继	
			return *(S.elem + i + 1);
		}
	}
	printf("没有该元素\n");
	return 0;
}

//遍历顺序表
void Traverse(SqList S) {
	for (int i = 0; i < S.len; ++i) {
		printf("%d ", *(S.elem + i));
	}
	printf("\n");
}

int main() {
	SqList S1;
	InitList(&S1);
	//填写 5 个数据
	for (int i = 0; i < 5; ++i) {
		*(S1.elem + i) = i + 1;
		++S1.len;
	}
	Traverse(S1);
	InsertElem(&S1, 4, 100);
	Traverse(S1);
	int value = GetElem(S1, 4);
	printf("%d\n", value);
	LocateElem(S1, 100);
	int prori_e = ProriElem(S1, 100);
	printf("%d\n", prori_e);
	int next_e = NextElem(S1, 100);
	printf("%d\n", next_e);
	DelElem(&S1, 4);
	Traverse(S1);
	system("pause");
	return 0;
}

效果图
数据结构之静态顺序表和动态顺序表_第2张图片

希望大家能够理解!!!

你可能感兴趣的:(基础,c语言,数据结构,C语言数据结构)