顺序表

顺序表:动态增长的数组,头部和中间插入效率极低
优点:cpu高级缓存利用率高,很多算法最好用数组

头文件"seqlist.h"

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<windows.h>
#include<cstdio>
#include<malloc.h>
#include<assert.h>
#define SEQLIST_INIT_SIZE 8
#define INC_SIZE 3  //空间增量的大小,而非翻倍增加
typedef int EType;  //此处int可以换为任意类型
typedef struct Seqlist 
{
	EType *base;
	int capacity;  //顺序表容量
	int size;  //表的大小
} Seqlist;
//实现以下功能
void show();  //打印菜单
int Check(Seqlist *list);  //增加顺序表的容量
void InitSeqlist(Seqlist *list);  //初始化顺序表
void showlist(Seqlist *list);  //打印顺序表
void pushback(Seqlist *list, EType x);  //尾插
void pushfront(Seqlist *list, EType x);  //头插
void popback(Seqlist *list);  //尾删
void popfront(Seqlist *list);  //头删
void insertpos(Seqlist *list, int pos, EType x);  //在顺序表选定下标位置插入数据
int find(Seqlist *list, EType key);  //查找顺序表中元素key的下标
int length(Seqlist *list);  //求顺序表长度
void deletepos(Seqlist *list, int pos);  //删除顺序表中选定下标位置元素
void deleteval(Seqlist *list, int key);  //删除顺序表中值为key的元素
void sort(Seqlist *list);  //冒泡排序
void reverse(Seqlist *list);  //逆置顺序表
void clear(Seqlist *list);  //清除顺序表元素
void destroy(Seqlist *list);  //销毁顺序表
void merge(Seqlist *lt, Seqlist *la, Seqlist *lb);  //合并两个顺序表

源文件"seqlist.cpp"

#include"seqlist.h"
void show()  //打印菜单
{
	printf("*************************\n");
	printf("1 .尾插\n3 .头插  \n");
	printf("3 .打印\n4 .尾删  \n");
	printf("5 .头删\n6 .指定插入 \n");
	printf("7 .查询\n8 .测长度 \n");
	printf("9 .根据指定位置删除 \n10.根据指定元素删除 \n");
	printf("11.冒泡排序\n12.逆置 \n");
	printf("13.清空\n14.合并两个顺序表 \n");
	printf("0.退出程序\n");
	printf("*************************\n");
	printf("请选择:>>");
}
int Check(Seqlist *list)  //增加顺序表的容量
{
	EType *newbase = (EType*)realloc(list, sizeof(EType)*(list->capacity + INC_SIZE));
	//重新分配内存空间
	if (newbase == NULL) 
	{
		printf("内存空间已满,无法再分配内存空间!\n");
		return false;
	}
	list->base = newbase;  //改变指针的指向
	list->capacity += INC_SIZE;
	return true;
}
void InitSeqlist(Seqlist *list)  //初始化顺序表
{
	list->base = (EType*)malloc(sizeof(EType)*SEQLIST_INIT_SIZE);  //开辟空间初始化
	assert(list->base != NULL);
	list->capacity = SEQLIST_INIT_SIZE;  //容量空间
	list->size = 0;
}
void pushback(Seqlist *list, EType x)  //尾插
{
	if (list->size >= list->capacity && !Check(list))
	{ //Inc(list)用来判断增加顺序表容量是否成功,只有在失败的情况下才会进入if语句中
		printf("顺序表容量已满,无法再在表尾继续插入新元素!\n");
		return;
	}
	list->base[list->size] = x;
	list->size++;
}
void pushfront(Seqlist *list, EType x)  //头插
{
	if (list->size >= list->capacity && !Check(list))
	{
		printf("顺序表容量已满,无法再在表头插入新元素!\n");
		return;
	}
	for (int i = list->size; i > 0; i--)  //向后移动整个顺序表
		list->base[i] = list->base[i - 1];
	list->base[0] = x;
	list->size++;
}
void showlist(Seqlist *list)  //打印顺序表
{
	for (int i = 0; i < list->size; i++)
		printf("%d ", list->base[i]);
	printf("\n");
}
void popback(Seqlist *list)  //尾删
{
	if (list->size == 0)
	{
		printf("顺序表已空,无法再在表尾删除元素!\n");
		return;
	}
	list->size--;  //顺序表的大小-1,即删除最后一个元素
}
void popfront(Seqlist *list)  //头删
{
	if (list->size == 0) 
	{
		printf("顺序表已空,无法再在表头删除元素!\n");
		return;
	}
	for (int i = 0; i < list->size - 1; i++)  //顺序表向前覆盖
		list->base[i] = list->base[i + 1];
	list->size--;  //删除最后一个位置
}
void insertpos(Seqlist *list, int pos, EType x)  //在顺序表选定下标位置插入数据
{
	if (pos<0 || pos>list->size)  //下标在规定范围且不超出顺序表
	{
		printf("插入位置不合法,无法插入元素!\n");
		return;
	}
	if (list->size >= list->capacity && !Check(list))
	{
		printf("顺序表容量已满,无法在插入新的元素!\n");
		return;
	}
	for (int i = list->size; i > pos; i--)  //类似头插
		list->base[i] = list->base[i - 1];
	list->base[pos] = x;
	list->size++;
}
int find(Seqlist *list, EType key)  //查找顺序表中元素key的下标
{
	for (int i = 0; i < list->size; i++)  //遍历一遍顺序表
	{
		if (list->base[i] == key)
			return i;
	}
	return -1;
}
int length(Seqlist *list)  //求顺序表长度
{
	return list->size;
}
void deletepos(Seqlist *list, int pos)  //删除顺序表中选定下标位置元素
{
	if (pos < 0 || pos >= list->size) 
	{
		printf("删除位置不合法,无法删除元素!\n");
		return;
	}
	for (int i = pos; i < list->size - 1; i++)  //类似头删
		list->base[i] = list->base[i + 1];
	list->size--;
}
void deleteval(Seqlist *list, int key)   //删除顺序表中值为key的元素
{
	int pos = find(list, key);
	if (pos == -1) 
	{
		printf("顺序表中没有这个元素!\n");
		return;
	}
	deletepos(list, pos);
}
void sort(Seqlist *list)  //冒泡排序,由小到大
{
	for (int i = 0; i < list->size - 1; i++)
	{   //排序的趟数(例如5个数据需要比较4趟)
		for (int j = 0; j < list->size - 1 - i; j++)
		{   //每一趟比较中的比较次数(例如5个数据在第0趟需要比较4次)
			if (list->base[j] > list->base[j + 1]) 
			{
				EType temp = list->base[j];
				list->base[j] = list->base[j + 1];
				list->base[j + 1] = temp;
			}
		}
	}
}
void reverse(Seqlist *list)  //逆置顺序表
{
	if (list->size == 0 || list->size == 1) return;
	int low = 0, high = list->size - 1;
	while (low < high) 
	{
		EType temp = list->base[low];
		list->base[low] = list->base[high];
		list->base[high] = temp;
		low++;
		high--;
	}
}
void clear(Seqlist *list)  //清除顺序表元素
{
	list->size = 0;
}
void destroy(Seqlist *list)  //销毁顺序表
{
	free(list->base);
	list->base = NULL;
	list->capacity = 0;
	list->size = 0;
}
void merge(Seqlist *list, Seqlist *alist, Seqlist *blist)  //合并两个顺序表
{
	list->capacity = alist->size + blist->size;
	list->base = (EType*)malloc(sizeof(EType)*list->capacity);
	assert(list->base != NULL);
	int ia = 0, ib = 0, ic = 0;
	while (ia < alist->size&&ib < blist->size)
	{
		if (alist->base[ia] < blist->base[ib]) 
			list->base[ic++] = alist->base[ia++];
		else
			list->base[ic++] = blist->base[ib++];
	}
	while (ia < alist->size) 
		list->base[ic++] = alist->base[ia++];
	while (ib < blist->size) 
		list->base[ic++] = blist->base[ib++];
	list->size = alist->size + blist->size;
	showlist(list);
}

主函数"main.cpp"

#include"seqlist.cpp"
int main()
{
	Seqlist list;
	InitSeqlist(&list);
	EType num;
	int pos;
	int chose = 1;
	while (chose)
	{
		show();
		scanf("%d", &chose);
		if (chose == 0) break;
		switch (chose)
		{
		case 1:  //尾插
			printf("请输入要插入的数据(-1结束):>");
			while (scanf("%d", &num), num != -1)  //先输入item的值,只要item不等于-1就接着循环
				pushback(&list, num);
			break;
		case 2:  //头插
			printf("请输入要插入的数据(-1结束):>");
			while (scanf("%d", &num), num != -1)
				pushfront(&list, num);
			break;
		case 3:  //打印顺序表
			showlist(&list);
			break;
		case 4:  //尾删
			popback(&list);
			break;
		case 5:  //头删
			popfront(&list);
			break;
		case 6:  //在顺序表选定下标位置插入数据
			printf("请输入要插入的位置:>");
			scanf("%d", &pos);
			printf("请输入要插入的数据:>");
			scanf("%d", &num);
			insertpos(&list, pos, num);
			break;
		case 7:  //查找顺序表中元素key的下标
			printf("请输入要查找的数据:>");
			scanf("%d", &num);
			pos = find(&list, num);
			if (pos == -1)
				printf("查找的数据元素不在顺序表中!\n");
			else
				printf("查找的数据元素在顺序表中的下标位置为%d\n", pos);
			break;
		case 8:  //求顺序表长度
			printf("顺序表的长度为%d\n", length(&list));
			break;
		case 9:  //删除顺序表中选定下标位置元素
			printf("请输入要删除数据在顺序表中的下标位置:>");
			scanf("%d", &pos);
			deletepos(&list, pos);
			break;
		case 10:  //删除顺序表中值为key的元素
			printf("请输入要删除数据的值:>");
			scanf("%d", &num);
			deleteval(&list, num);
			break;
		case 11:  //冒泡排序
			sort(&list); break;
		case 12:  //逆置顺序表
			reverse(&list); break;
		case 13:  //清除顺序表
			clear(&list); break;
		case 14:  //合并两个顺序列表
			Seqlist alist, blist;  //先初始化两个顺序表
			EType item1, item2;  //也可以递上面定义的链表,但是仍需在定义一个链表
			InitSeqlist(&alist);  
			InitSeqlist(&blist);
			printf("请输入顺序表1中的元素值(-1结束):>");
			while (scanf("%d", &item1), item1 != -1)  //给两个顺序表添加元素
				pushback(&alist, item1);  //尾插
			printf("请输入顺序表2中的元素值(-1结束):>");
			while (scanf("%d", &item2), item2 != -1)
				pushback(&blist, item2);  //尾插
			merge(&list, &alist, &blist);  //合并函数
			destroy(&alist);  //合并后销毁原顺序表
			destroy(&blist);
			break;
		default:  //输出其他违规
			printf("输入的选择错误!请重新输入!\n");
			break;
		}
	}
	destroy(&list);  //退出时销毁
	system("pause");
	return 0;
}
本项目是一个基于SSM(Spring+SpringMVC+MyBatis)框架和Vue.js前端技术的大学生第二课堂系统,旨在为大学生提供一个便捷、高效的学习和实践平台。项目包含了完整的数据库设计、后端Java代码实现以及前端Vue.js页面展示,适合计算机相关专业的毕设学生和需要进行项目实战练习的Java学习者。 在功能方面,系统主要实现了以下几个模块:用户管理、课程管理、活动管理、成绩管理和通知公告。用户管理模块支持学生和教师的注册、登录及权限管理;课程管理模块允许教师上传课程资料、设置课程时间,并由学生进行选课;活动管理模块提供了活动发布、报名和签到功能,鼓励学生参与课外实践活动;成绩管理模块则用于记录和查询学生的课程成绩和活动参与情况;通知公告模块则实时发布学校或班级的最新通知和公告。 技术实现上,后端采用SSM框架进行开发,Spring负责业务逻辑层,SpringMVC处理Web请求,MyBatis进行数据库操作,确保了系统的稳定性和扩展性。前端则使用Vue.js框架,结合Axios进行数据请求,实现了前后端分离,提升了用户体验和开发效率。 该项目不仅提供了完整的源代码和相关文档,还包括了详细的数据库设计文档和项目部署指南,为学习和实践提供了便利。对于基础较好的学习者,可以根据自己的需求在此基础上进行功能扩展和优化,进一步提升自己的技术水平和项目实战能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值