顺序表的定义
涉及结构体的使用和顺序表的增删查改
结构体的使用
1.结构体变量的定义可以放在结构体的声明之后
struct 结构体名{
成员列表;
};
struct Student{
char name[20];
int num;
float score;
};//结构体的声明
//定义结构体变量
struct Student stu1;
2.在声明结构体时定义结构体变量
struct Student{ //结构体名为Student
char name[20];
int num;
float score;
}stu1; //在定义之后跟变量名
3.还可以使用匿名结构体来定义结构体变量:
struct { //没有结构名
char name[20];
int num;
float score;
}stu1;
//要注意的是这样的方式虽然简单,
//但不能再次定义新的结构体变量了。
typedef关键字 进行数据类型重命名
typedef <数据类型> <别名>
typedef int zhengshu;
typedef int *zhengshuzhizhen;
int x=1; 等价于 zhengshu x=1;
int *p; 等价于 zhengshuzhizhen p;
struct LNode{ //定义单链表结点类型,结构体名为LNode
ElemType data;//每个结点存放一个数据元素
struct LNode *next;//指针指向下一个节点
};
//增加一个新的结点,在内存中申请一个节点所需的空间,并用指针p指向这个结点
struct LNode *p=(stuct LNode *)malloc(sizeof(struct LNode));
//因为每次申请空间都要用struct LNode这么长的名称不方便,
//所以就想到使用typedef来对结构体的数据类型进行重命名
typedef struct LNode LNode;//相当于使用typedef把struct Lnode替换成LNode
//就可以采用如下表达方式,比较简洁
LNode *p = (LNode *) malloc(sizeof(LNode));
访问结构体成员
用结构成员运算符 .
访问结构成员的一般形式为:结构体变量名.成员名
如 stu1.name 表示学生stu1的名字
但如果结构体中的成员有事一个结构体:
struct Birthday{ //声明结构体 Birthday
int year;
int month;
int day;
};
struct Student{ //声明结构体 Student
char name[20];
int num;
float score;
struct Birthday birthday; //生日
}stu1;
//则用stu1.birthday.year来访问出生的年份
结构体变量的初始化
1.结构体变量的初始化可以放在定义之后
struct Student stu1, stu2; //定义结构体变量
strcpy(stu1.name, "Jack");
stu1.num = 18;
stu1.score = 90.5;
注意不能直接给数组名赋值,因为数组名是一个常量。
stu1.name = "Jack";
//不能这样写,数组名指向此数组中第一个元素的位置,是一个常量
可以对结构体进行整体赋值:
stu2 = (struct Student){"Tom", 15, 88.0};
//注意:此时要进行强制类型转换,因为数组赋值也是使用{},
//不转换的话系统无法区别是对数组还是对结构体赋初值
int array[5]={0,1,2,3,4};//数组初始化
stu2 = {"Tom", 18, 99.0};//会报错,必须加上(struct Student)强制类型转换
2.结构体变量的初始化也可以与定义同时:
struct Student{ //声明结构体 Student
char name[20];
int num;
float score;
}stu = {"Mike", 15, 91};
//注意初始化值的类型和顺序要与结构体声明时成员的类型和顺序一致
//这时不需要强制类型转换
//也可以选择部分初始化
struct Student stu4={.name = "Mary"};
//也可以按照任意的顺序使用指定初始化项目:
struct Student st = { .name = "Smith",
.score = 90.5,
.num = 18 };
更深入的内容请参考这篇博客
C语言中的结构体
静态顺序表的增删查改
这里使用c++写的
注意
1)线性表中的元素的位序是从1开始的,而数组中元素下标是从0开始的
2)要对表进行插入或删除时,c++中要使用 & 引用符号,而C中不能使用&,C中使用的指针,若使用指针,则引用结构体中的元素时就要使用->, 而不是结构成员运算符 .
3)在插入和删除时应注意程序的健壮性(容错性)
注意在删除和插入时要修改 L.len
//静态链表的增删查改
#include<stdio.h>
#define Maxsize 20//顺序表的最大长度
//线性表的顺序表示
typedef struct{
int data[Maxsize];//顺序表的元素
int len;//顺序表的当前长度
}SqList;
void InitList(SqList &L){
for(int i=0;i<Maxsize;i++){
L.data[i]=0;
}
L.len=0;
}
int Length(SqList L){
return L.len;
}
//按值查找
int LocateElem(SqList L,int e){
for(int i=0; i<L.len;i++){
if(L.data[i] == e)
return i+1;//返回此元素在顺序表中的位置(从1开始)
}
return 0;//未找到
}
//按位查找
int GetElem(SqList L,int i){
if(i<1||i>L.len){
printf("非法位序!\n");
return 0;//位置非法
}
return L.data[i-1];
}
//在L的第i个位置上插入e @@@判断是否超出MaxSize
bool InsertList(SqList &L,int i,int e){
if(i < 1 || i > L.len+1)//插入位置不合法
return false;
if(L.len > Maxsize)
return false;
for(int j = L.len; j >= i; j--){//把i后面的都往后移动一个位置
L.data[j]=L.data[j-1];
}
L.data[i-1]=e;//@@@
L.len++;//@@@
return true;//插入成功
}
//删除操作,删除L中第i个位置的元素,用e返回删除元素的值
bool DeleteList(SqList &L,int i,int &e){
if(i<1||i>L.len)
return false;//删除位置不合法
e=L.data[i-1];//@@@
for(int j=i-1;j<L.len;j++){//@@@
L.data[j]=L.data[j+1];
}
L.len--;
return true;
}
void PrintList(SqList L){
printf("(length:%d)List is: ",L.len);
for(int i = 0; i < L.len; i++){
printf("%d ",L.data[i]);
}
printf("\n");
}
bool Empty(SqList L){
return L.len==0;
}
void DestroyList(SqList &L){
L.len=0;
}
int main(){
SqList L;//声明一个顺序表
InitList(L);
for(int i=0; i<10; i++){
InsertList(L,i+1,i+1);
}
printf("插入后的链表为:\n");
PrintList(L);
int e;
printf("\n");
if(DeleteList(L,6,e)){
printf("%d ",e);
}
printf("\n");
InsertList(L,10,e);
PrintList(L);
int i=GetElem(L,11);
if(i){
printf("数值是:%d\n",i);
}
DestroyList(L);
PrintList(L);
return 0;
}