#ifndef _SEQLIST_H_
#define _SEQLIST_H_
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#define MAX 40 //定义顺序表的最大容量
typedef int datatype; //数据元素的类型,以整形为例
//定义顺序表类型
typedef struct
{
datatype data[MAX]; //存储数据元素的数组
int len; //存储当前顺序表的长度
}seqList,*seqListPtr; //重命名为一个结构体变量,和一个指针类型
//创建顺序表
seqListPtr list_create();
//判满
int list_full(seqListPtr s);
//判空
int list_empty(seqListPtr s);
//向顺序表中添加元素
int list_add(seqListPtr s,datatype e);
//遍历顺序表
void list_show(seqListPtr s);
//任意位置插入元素
void list_insert(seqListPtr s,int pos,datatype e);
//任意位置删除元素
//按位置进行修改
//查找指定位置的元素
//按值进行查找元素
int list_search_value(seqListPtr s,datatype e);
//将顺序表排序(flag等于1则为升序,0为降序,用选择排序)
void list_sort(seqListPtr s,int flag);
//顺序表去重
//扩容
//求最值操作(1为最大值,0为最小值)
datatype list_mvalue(seqListPtr s,int flag);
//顺序表反转
void list_reverse(seqListPtr s);
//释放顺序表
#endif
#include"seqlist.h"
//创建顺序表
seqListPtr list_create()
{
//在堆区申请一个顺序表的空间大小
seqListPtr s = (seqListPtr)malloc(sizeof(seqList));
//判断是否申请成功
if(NULL == s)
{
printf("顺序表创建失败\n");
return NULL;
}
//此时顺序表创建成功
memset(s -> data,0,sizeof(s -> data)); //清空数组
s -> len = 0; //数组长度清零
printf("顺序表创建成功\n");
return s;
}
//判满,成功返回真,失败返回假
int list_full(seqListPtr s)
{
//判断逻辑
if(NULL == s)
{
printf("所给顺序表不合法\n");
return 0;
}
//合法则返回是否已经满
return s -> len == MAX;
}
//判空,空返回真,非空返回假
int list_empty(seqListPtr s)
{
//判断逻辑
if(NULL == s)
{
printf("所给顺序表不合法\n");
return 0;
}
//合法返回是否空
return s -> len == 0;
}
//向顺序表中添加元素
int list_add(seqListPtr s,datatype e)
{
//判断逻辑
if(NULL == s || list_full(s))
{
printf("添加失败\n");
return -1;
}
//添加逻辑
s -> data[s -> len] = e; //将新元素放入最后一个位置
//表的变化
s -> len++;
printf("添加成功\n");
return 1;
}
//遍历顺序表
void list_show(seqListPtr s)
{
//判断逻辑
if(NULL == s || list_empty(s))
{
printf("遍历失败\n");
return;
}
//遍历逻辑
printf("当前顺序表的元素分别是; ");
for(int i = 0; i < s -> len; i++)
{
printf("%d\t",s -> data[i]);
}
printf("\n");
}
//任意位置插入元素
void list_insert(seqListPtr s,int pos,datatype e)
{
//判断逻辑
if(NULL == s || list_full(s) || pos > s -> len || pos < 0 )
{
printf("插入不合法\n");
return;
}
//腾空过程
for(int i = s -> len - 1; i >= pos; i--)
{
s -> data[i + 1] = s -> data[i];
}
//插入逻辑
s -> data[pos] = e;
//表的变化
s -> len++;
printf("插入成功\n");
}
//按值进行查找元素
int list_search_value(seqListPtr s,datatype e)
{
//判断逻辑
if(NULL == s)
{
printf("查找不合法\n");
return;
}
//查找过程
for(int i = 0; i < s -> len; i++)
{
if(s -> data[i] == e)
{
printf("找到了\n");
return i;
}
}
return -1;
}
//将顺序表排序(flag等于1则为升序,0为降序,用选择排序)
void list_sort(seqListPtr s,int flag)
{
//判断逻辑
if(NULL == s)
{
printf("不合法\n");
return;
}
int i = 0;
int j = 0;
int index = 0;
//进行排序
if(flag == 1)
{
for(i = 1; i < s -> len; i++)
{
index = i - 1;
for(j = i - 1; j < s -> len; j++)
{
if(s -> data[j] < s -> data[index])
{
index = j;
}
}
if(index != i - 1)
{
int tmp = s -> data[index];
s -> data[index] = s -> data[i - 1];
s -> data[i - 1] = tmp;
}
}
}
else if(flag == 0)
{
for(i = 1; i < s -> len; i++)
{
index = i - 1;
for(j = i - 1; j < s -> len; j++)
{
if(s -> data[j] > s -> data[index])
{
index = j;
}
}
if(index != i - 1)
{
int tmp = s -> data[index];
s -> data[index] = s -> data[i - 1];
s -> data[i - 1] = tmp;
}
}
}
}
//求最值操作(1为最大值,0为最小值)
datatype list_mvalue(seqListPtr s,int flag)
{
//判断逻辑
if(NULL == s)
{
printf("不合法\n");
return;
}
//求最值操作
int max = s -> data[0];
int min = s -> data[0];
if(flag == 1)
{
for(int i = 0; i < s -> len; i++)
{
if(s -> data[i] > max)
{
max = s -> data[i];
}
}
return max;
}
else if(flag == 0)
{
for(int i = 0; i < s -> len; i++)
{
if(s -> data[i] < min)
{
min = s -> data[i];
}
}
return min;
}
}
#include"seqlist.h"
int main(int argc,const char * argv[])
{
//申请一个顺序表
seqListPtr s = list_create();
if(NULL == s)
{
return -1;
}
//调用添加函数
list_add(s,3);
list_add(s,8);
list_add(s,2);
list_add(s,4);
//调用遍历函数
list_show(s);
printf("请输入插入的位置: ");
int pos = 0;
scanf("%d",&pos);
printf("请输入插入的元素: ");
datatype e;
scanf("%d",&e);
//调用插入函数
list_insert(s,pos,e);
list_show(s);
int value = 0;
printf("请输入要查找的值: ");
scanf("%d",&value);
//调用按值查找函数
int ret = list_search_value(s,value);
if(ret >= 0)
{
printf("这个值的下标是: %d",ret);
}
else
{
printf("没这个元素\n");
}
printf("\n");
int flag = 0;
printf("请选择升序还是降序(1 | 0): ");
scanf("%d",&flag);
//调用排序函数
list_sort(s,flag);
list_show(s);
printf("请选择求最大值还是最小值: ");
scanf("%d",&flag);
//调用求最值函数
datatype m = list_mvalue(s,flag);
if(flag == 1)
{
printf("最大值是%d",m);
}
else if(flag == 0)
{
printf("最小值是%d",m);
}
printf("\n");
return 0;
}
1、static在C语言中的用法
I、静态局部变量
改变了存储类型,使它的生命周期变长
II、静态全局变量
静态全局变量可以把全局变量的外部链接属性变成内部链接属性,使得这个变量只能在自己所在的.c文件内部使用,不能在其他的.c文件内部使用
III、静态函数
其实和静态全局变量是相似的,函数也是具有外部链接属性,可以被其他的.c文件内部使用,为了不被外部的.c文件使用,就可以使用static修饰,变成具有内部链接属性的函数
2、const 在C语言中的用法
I、修饰普通变量,使普通变量的值不能被改变
II、修饰指针变量,可以使指针的指向或指向地址的值或者两者都不能被改变
III、修饰函数形参,使得函数形参所指向的地址的值不能被改变
3、结构体中字节对齐原则
I、在结构体中的每个属性会根据自己所占内存大小,来设置起始存储位置,起始存储位置必须是自身类型的整数倍
II、在上面对齐的基础上,最后整体会进行一次对齐,整体的字节个数要是一个数据的整数倍,这个数据是系统字节对齐和结构体中最大成员所占字节的之间取最小值。min(系统对齐字节数,结构体中所占内存最大的字节数)
4、数据存储的逻辑结构有哪些,什么逻辑结构
I、集合结构:任意两个数据元素之间没有任何关系,只是单纯存储在同一个集合中(例如:公交车上的每个乘客)
II、线型结构:数据元素之间存在一对一的关系,在该结构中,除了第一个元素没有前驱,最后一个元素没有后继,其余所有数据都有且只有一个前驱和一个后继,(例如:排队做核酸)
III、树形结构:数据元素之间存在一对多的关系。(例如:族谱、公司组织架构)
IV、图形结构:数据元素之间存在多对多的关系。(例如:朋友关系)
5、数据结构的存储结构是什么,分别有哪些
I、顺序存储:将逻辑上连续的数据元素,存储在物理内存也连续的空间内;(例如:一根藤上七个娃)
II、链式存储:将逻辑上相邻的数据元素,存储在物理内存上随机位置;(例如︰银行柜台等待办理业务的用户)
III、索引存储:在存储数据元素时,单独创建一个索引表记录数据元素所在位置;(例如:课本的目录)
IV、散列存诸:也叫哈希存储,数据元素存储的位置跟数据元素的关键字有关。
6、宏函数与函数的区别
I、在编译时,对于宏定义函数而言,预编译时会将这些宏定义函数按展开的规则直接展开成语句,并且宏定义函数在代码中书写多少次,便展开多少次,拷贝相应的代码插入,生成相应的指令,而对于普通函数而言其只会生成一份相应的指令,调用处会生成传参指令和调用指令实现对函数的调用。
II、在实际执行过程中,宏定义式函数所有的语句都是普通语句执行,而普通函数由于需要调用的缘故,需要进行开辟栈空间、压栈、出栈等操作。
7、宏定义与typedef的区别
I、typedef是在编译阶段生效的,而宏定义是在预处理阶段生效的,不消耗编译时间。
II、 typedef可以定义结构体、联合体、枚举等复杂的数据类型,而宏定义只能进行简单的文本替换
III、typedef定义的新类型会增加代码的可读性和可维护性,而宏定义可能会导致代码可读性下降,并且容易出现错误。
IV、在使用typedef定义的新类型时,编译器会进行类型检查,而宏定义不会进行类型检查。