线性表顺序存储结构
先看看官方是怎么定义线性表的吧!
#include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 20 /* 存储空间初始分配量 */ typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */ typedef int Elemtype; /* ElemType类型根据实际情况而定,这里假设为int
看完了小朋友们所需的生长元素,接下来就开创造小朋友们吧!
typedef struct { ElemType data[MAXSIZE]; /* 数组,存储数据元素 */ int length; /* 线性表当前长度 */ }SqList;
小朋友们被造好之后,咱们为了让小朋友们站的更整齐些,于是画一行正方形的位置块,让每个小朋友们手拉着手站在各自的块里,像下面这样
/* 初始化顺序线性表 */ Status InitList(SqList *L) { L->length = 0; return OK; }
画完格子后,怕有些淘气的小朋友们站在格子里玩耍,咱们得先看看格子里是不是空的
Status ListEmpty(SqList L) { if (L.length == 0) { return TRUE; } else{ return FALSE; } }
如果此时有小朋友们站在格子里,咱们得告诉他,让他离开,使格子里面没有小朋友
/* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */ Status ClearList(SqList *L) { L->length = 0; return OK; }
现在有新来的小朋友加入我们,那么咱们让新来的小朋友手去她喜欢的格子里,然后开始做游戏了
Status ListInsert(SqList *L, int i, ElemType e) { int k; if (L->length == MAXSIZE) /* 顺序线性表已经满 */ { return ERROR; } if (i<1 || i>L->length+1)/* 当i比第一位置小或者比最后一位置后一位置还要大时 */ { return ERROR; } if (i <= L->length) { for (k = L->length - 1; k >= i - 1; k--) { L->data[k + 1] = L->data[k]; } } L->data[i - 1] = e; L->length++; return OK; }
但是有的小朋友们不乖,骚扰左右的小朋友,因此,需要让他出队面壁思过去
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */ /* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */ Status ListDelete(SqList *L, int i, ElemType *e) { int k; if (L->length = 0) /* 线性表为空 */ { return ERROR; } if (i<1 || i>L->length - 1) /* 删除位置不正确 */ { return ERROR; } *e = L->data[i]; if (i < L->length) /* 如果删除不是最后位置 */ { for (k = i; k < L->length; k++) /* 将删除位置后继元素前移 */ { L->data[k-1] = L->data[k]; } } L->length--; return OK; }
在整个队列里面,花花小朋友表现得最好,咱们数数花花在哪个位置吧
int LocateElem(SqList L, ElemType e) { int i=0; if (i >= L.length || L.length==0) { return 0; } for (i = 0; i < L.length; i++) { if (L.data[i] == e) { break; } } return i + 1; }
咱们再来查查哪个小朋友站在第i个位置啊
Status GetElem(SqList L, int i, ElemType *e) { if (i < 1 || i > L.length || L.length == 0) { return ERROR; } *e = L.data[i-1]; return OK; }
小朋友们表现得都很不错,咱们现在来看看一共有多少个小朋友参加这个游戏
int ListLength(SqList L) { return L.length; }
小朋友们这个游戏好不好玩啊!好玩的话,请大家记住好自己的位置,咱们下次再继续玩!
Status ListTraverse(SqList L) { int i; for (i = 0; i < L.length; i++) { printf("%d", L.data[i]); } printf("\n"); return OK; }
好了,咱们开始测试一下,咱们的代码吧!
void unionL(SqList *La, SqList Lb) { int La_len, Lb_len, i; ElemType e; La_len = ListLength(*La); Lb_len = ListLength(Lb); for (i = 1; i <= Lb_len; i++) { GetElem(Lb, i, &e); if (!LocateElem(*La, e)) ListInsert(La, ++La_len, e); } } int main() { SqList L; SqList Lb; ElemType e; Status i; int j, k; i = InitList(&L); printf("初始化L后:L.length=%d\n", L.length); for (j = 1; j <= 5; j++) i = ListInsert(&L, 1, j); printf("在L的表头依次插入1~5后:L.data="); ListTraverse(L); printf("L.length=%d \n", L.length); i = ListEmpty(L); printf("L是否空:i=%d(1:是 0:否)\n", i); i = ClearList(&L); printf("清空L后:L.length=%d\n", L.length); i = ListEmpty(L); printf("L是否空:i=%d(1:是 0:否)\n", i); for (j = 1; j <= 10; j++) ListInsert(&L, j, j); printf("在L的表尾依次插入1~10后:L.data="); ListTraverse(L); printf("L.length=%d \n", L.length); ListInsert(&L, 1, 0); printf("在L的表头插入0后:L.data="); ListTraverse(L); printf("L.length=%d \n", L.length); GetElem(L, 5, &e); printf("第5个元素的值为:%d\n", e); for (j = 3; j <= 4; j++) { k = LocateElem(L, j); if (k) printf("第%d个元素的值为%d\n", k, j); else printf("没有值为%d的元素\n", j); } k = ListLength(L); /* k为表长 */ for (j = k + 1; j >= k; j--) { i = ListDelete(&L, j, &e); /* 删除第j个数据 */ if (i == ERROR) printf("删除第%d个数据失败\n", j); else printf("删除第%d个的元素值为:%d\n", j, e); } printf("依次输出L的元素:"); ListTraverse(L); j = 5; ListDelete(&L, j, &e); /* 删除第5个数据 */ printf("删除第%d个的元素值为:%d\n", j, e); printf("依次输出L的元素:"); ListTraverse(L); //构造一个有10个数的Lb i = InitList(&Lb); for (j = 6; j <= 15; j++) i = ListInsert(&Lb, 1, j); unionL(&L, Lb); printf("依次输出合并了Lb的L的元素:"); ListTraverse(L); getchar(); return 0; }
总结:
1、首先关于表里功能函数的形参问题,有的形参被设定为 SqList *L,而有的为SqList L,这个得看需对整个列表做什么操作了,如果需要对整个列表进行初始化、插入、删除、设为空,则形参应为SqList *L,若对列表操作仅仅是查找,打印,不影响整个列表的框架操作,形参则设置为SqList L。
2、关于L->length和L.length的问题
若功能函数的形参为SqList *L,则可以进行L->length操作,若功能函数的形参为SqList L,则可以进行L.length操作。
首先L->length是对整个序列中元素的序号进行操作的,若L->length=0;则表示将序列清空 ,若L->length==n,则序列里有n个元素。
而L.length则表示的是序列最后一个元素的序号,若L.length==0,则表示序列为空表,若L.length==n,同样也表示为序列里有你个元素