参考书籍《数据结构第二版——严蔚敏》
笔记暂时纪录在这,后续如果有改进和修改会同步更新
数据结构定义说明
typedef int element; //顺序表的数据存储类型,这里以int型举例,
//也可以是自己定义的结构体,如果这里改了后面涉及到相应的算法也要改
#define Sqmaxlength 100 //顺序表的最大长度,在为顺序表分配空间时使用
typedef struct _Sqlist {
element *Sqdata;
int Length;
/*补充一点 在内存中这个结构体在本例中站8字节,其中int*的指针占4字节,Length占4字节,
要找到具体的数据需要跳转到Sqdata所指的内存中才有*/
}SqList;//线性表的数据结构
顺序表的一些常用函数
int InitSqL(SqList* L, int length);//初始化一个线性表
int GetElem(SqList* L, int i, element* e);//将顺序表中指定元素取到e中
void MergeList_Sq(SqList LA, SqList LB, SqList* LC);//顺序表的合并,将LA,LB,合并成LC
int LocateElem(SqList* L, element e);判断表中是否有元素e,如果有返回1,没有返回0
int SqInsert(SqList* L, int i, element e);//线性表的插入
int SqLDelete(SqList* L, int i, element* e);//删除顺序表中的某个元素,删除后数据由e接取
int SqLDestroy(SqList* L);//销毁顺序表(释放内存)
void SqLClear(SqList* L);//清空顺序表
void MergeList(SqList* LA, SqList* LB);//顺序表的合并,将LA,LB,合并到LA,没有顺序,但会把重复的去除
具体的实现代码如下:
//初始化一个线性表
int InitSqL(SqList *L,int length) {
L->Sqdata = (element*)malloc(sizeof(element)*Sqmaxlength);
if (!(L->Sqdata)) return 0;
L->Length = 0;
return 1;
}
//将顺序表中指定元素取到e中,示例 element e; GetElem(LB, i, &e);
int GetElem(SqList *L,int i, element *e) {
if (i<1 || i>L->Length) return 0;
*e = L->Sqdata[i - 1];
return 1;
}
//判断表中是否有元素e,如果有返回1,没有返回0
int LocateElem(SqList* L, element e) {for (int i = 0; i < L->Length + 1; i++) {
if (e == L->Sqdata[i])
return 1;
}
return 0;
}
//删除顺序表中的某个元素,删除后数据由e接取
int SqLDelete(SqList* L, int i, element* e) {
if (i<1 || i>L->Length + 1) return 0;
*e = L->Sqdata[i - 1];//将数据传出来
for (int j = i; j < L->Length; j++)
L->Sqdata[i - 1] = L->Sqdata[i];//数据依次前移
L->Length--;
/*这里没有将原本最后一个元素的位置的数据删除,
不过也不影响,在使用是也不会读取到Length长度后面去*/
return 1;
}
//销毁顺序表(释放内存)
int SqLDestroy(SqList* L) {
if (L->Sqdata) {
free(L->Sqdata);
return 1;
}
else return 0;//为空,根本就没有分配内存,何来释放
}
//清空顺序表
void SqLClear(SqList* L) {//和上面删除某一个元素一样,不需要将数据覆盖
L->Length = 0;
}
/**
* @brief 顺序表的插入
* @param L:要操作的线性表
* @param i:位置将新元素放在第i个位置
* @param e:插入的元素的数据
* @retval NULL
*/
int SqInsert(SqList* L,int i, element e) {
if (i<1 || i>L->Length + 1) return 0;
if (L->Length == Sqmaxlength) return 0;
for (int j = L->Length - 1; j >= i - 1;j--) {
L->Sqdata[j + 1] = L->Sqdata[j];//从后向前,每个元素依次后移
}
L->Sqdata[i - 1] = e;//将要插入的插入第i个位置
L->Length++;//插入之后长度加一
return 1;
}
/**
* @brief 顺序的合并,将LA,LB,合并到LA,没有顺序,但会把重复的去除
* @param LA:SqList
* @param LB:SqList
* @retval NULL
*/
void MergeList(SqList* LA, SqList* LB) {
for (int i = 1; i < LB->Length + 1; i++) {
element e;
GetElem(LB, i, &e);
if (!LocateElem(LA, e)) {//如果没有此元素
LA->Sqdata[LA->Length++] = e;//将元素放到LA中,然后指针后移
}
}
}
/**
* @brief 线性表的合并,将LA,LB,合并成LC(顺序表小到大),LA,LB
* 不销毁
* @param LA:SqList
* @param LB:SqList
* @param LC:SqList &
* @retval NULL
*/
void MergeList_Sq(SqList LA, SqList LB, SqList* LC) {
element* pa, * pb, * pc;
pa = LA.Sqdata;
pb = LB.Sqdata;
LC->Length = LA.Length + LB.Length;
LC->Sqdata = (element*)malloc(sizeof(SqList) * Sqmaxlength);
if (LC->Sqdata != NULL) {//申请内存成功后才会进行
pc = LC->Sqdata;
element* pa_last = LA.Sqdata + LA.Length - 1; //pa_last指向LA的最后一个元素
element* pb_last = LB.Sqdata + LB.Length - 1;
while (pa <= pa_last && pb <= pb_last) {
if (*pa <= *pb) *pc++ = *pa++;//注意这里是先赋值后加
else *pc++ = *pb++;//依次写入两表中较小的
}
while (pa <= pa_last) *pc++ = *pa++;//这两步就是将剩余一个表的元素依次放入
while (pb <= pa_last) *pc++ = *pb++;
}
}
简单应用如下:
void test_SqList() {
/*问题引入
将两个多项式合并相加
Pa(x)=10 +5X -4X^2 +3X^3 +2X^4
Pb(x)=-3 +8X +4X^2 -5X^4 +7X^5 -2X^6
*/
SqList Pa_Sq;//定义Pa顺序表
InitSqL(&Pa_Sq,7);
SqInsert(&Pa_Sq, 1, 10);
SqInsert(&Pa_Sq, 2, 5);
SqInsert(&Pa_Sq, 3, -4);
SqInsert(&Pa_Sq, 4, 3);
SqInsert(&Pa_Sq, 5, 2);
SqInsert(&Pa_Sq, 6, 0);
SqInsert(&Pa_Sq, 7, 0);
SqList Pb_Sq;//定义Pb顺序表
InitSqL(&Pb_Sq, 7);
SqInsert(&Pb_Sq, 1, -3);
SqInsert(&Pb_Sq, 2, 8);
SqInsert(&Pb_Sq, 3, 4);
SqInsert(&Pb_Sq, 4, 0);
SqInsert(&Pb_Sq, 5, -5);
SqInsert(&Pb_Sq, 6, 7);
SqInsert(&Pb_Sq, 7, -2);
printf("Pa_Sq地址%p Pb_Sq地址%p\n", &Pa_Sq, &Pb_Sq);
SqList Pc_Sq;//定义Pc顺序表
InitSqL(&Pc_Sq, 7);//将结果存在Pc_Sq中
element pa,pb;
for (int i = 1; i < 8;i++) {
GetElem(&Pa_Sq,i,&pa);
GetElem(&Pb_Sq, i, &pb);
printf("pa=%d pb=%d pa+pb=%d\n", pa, pb, pa + pb);
SqInsert(&Pc_Sq, i,pa+pb);
}
printf("计算结束,开始输出\n");
for (int i = 1; i <= Pc_Sq.Length; i++)
printf("共%d个元素,第%d元素值为%d\n",Pc_Sq.Length,i,Pc_Sq.Sqdata[i-1]);
printf("示例结束");
}
上面这个函数放在主函数中运行结果如下: