【数据结构笔记备忘】顺序表

参考书籍《数据结构第二版——严蔚敏》

笔记暂时纪录在这,后续如果有改进和修改会同步更新

数据结构定义说明

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("示例结束");
}

上面这个函数放在主函数中运行结果如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值