前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言实现线性表的顺序表示

C语言实现线性表的顺序表示

作者头像
忆想不到的晖
发布2020-07-15 11:41:38
2.1K0
发布2020-07-15 11:41:38
举报
文章被收录于专栏:hui

文章目录
  • 线性表的常规操作
  • 定义顺序表结构体
  • 初始化顺序表
  • 顺序表的销毁
  • 清空顺序表
  • 顺序表判空
  • 求顺序表的长度
  • 顺序表的遍历
  • 顺序表的插入​(重点)
    • 算法实现
    • 表尾插入
    • 表中插入
  • 顺序表的删除​(重点)
  • 顺序表的查找​(重点)
    • 查找指定位置的顺序表元素
    • 查找顺序表指定元素的位置(第一个匹配成功的元素位置)
  • 源代码

线性表的常规操作

代码语言:javascript
复制
SeqList InitList();		// 初始化线性表
void DestroyList();		// 销毁线性表
void ClearList();		// 清空线性表
int ListEmpty();		// 判断线性表是否为空
int ListLength();		// 求线性表的长度
void Travel();			// 遍历线性表
int ListInsert();		// 向线性表插入元素
int ListDelete();		// 从线性表删除元素
int GetElem();			// 找到线性表指定位置的元素值
int LocateElem();		// 找到线性表指定元素值的位置

定义顺序表结构体

顺序表是有插入和删除操作的,所以顺序表的长度是变化的,而 C语言中的数组是定长 的,那么该如何用数组实现顺序表呢? 我们可以定义一个变量来表示顺序表的长度,当顺序表长度变化时,只需相应地更改该变量即可。

代码语言:javascript
复制
#include "stdio.h"
#include "malloc.h"

#define MAXSIZE 100		// 顺序表的最大存储量
#define TRUE  1
#define FALSE 0

typedef int ElemType;	// 顺序表存储元素的数据类型

// 定义顺序表结构体
typedef struct SeqList{
	ElemType elems[MAXSIZE];
	int len;			// 当前顺序表的长度
}*SeqList;

*SeqList 是结构体类型指针,这里指的就是顺序表的地址。

#define MAXSIZE 100 宏定义顺序表的最大存储量,更方便改顺序表的存储大小,耦合性低。

typedef int ElemType; 自定义顺序表元素类型的,看起来 ElemTypeint 是一样的,为什么不直接用 int,要用 ElemType

Because:

定义不同的数据类型名称是为了提高程序的 高内聚,低耦合 ,而且一旦你需要将数据类型变换其他类型比如使用char类型的了,

只要写:typedef char ElemType;一下子就全改了,如果没有定义的话就要一个个的把 int 改成 char,你不嫌麻烦么。

初始化顺序表

代码语言:javascript
复制
// 初始化顺序表
SeqList InitList(){
	SeqList list = (SeqList)malloc(sizeof(struct SeqList));		// 分配顺序表内存大小
	list -> len = 0;		// 顺序表的初始长度
	return list;
}

顺序表的销毁

有初始化操作肯定就会有销毁,销毁无用的资源是一个好习惯。 如果使用静态数组实现的顺序表,我们无需手动释放资源,因为程序结束后系统会自动释放内存;而如果使用动态内存分配实现的顺序表,就需要我们手动释放内存,实现如下:

代码语言:javascript
复制
#include "stdio.h"
#include "malloc.h"

#define MAXSIZE 100			// 顺序表的最大存储量
#define TRUE  1
#define FALSE 0

typedef int ElemType;		// 顺序表存储元素的数据类型

// 定义顺序表结构体
typedef struct SeqList{
	ElemType *elems;
	int len;				// 当前顺序表的长度
}*SeqList;

// 初始化顺序表
SeqList InitList(){
	SeqList list;
    list -> elems = (ElemType *)malloc(sizeof(ElemType) * MAXSIZE);		// 分配顺序表内存大小
	list -> len = 0;		// 顺序表的初始长度
	return list;
}

// 销毁顺序表
void DestroyList(SeqList list){
	if(list -> elems != NULL){
		free(list -> elems);	//释放动态数组内存
	}
	list -> elems = NULL;
	printf("释放动态数组内存\n");
}

int main(int argc, char const *argv[])
{
	SeqList list = InitList();
	printf("list -> len:%d\n", list -> len);
	DestroyList(list);
	printf("list -> elems地址:%p\n", list -> elems);
	return 0;
}

程序运行结果

代码语言:javascript
复制
list -> len:0
释放动态数组内存
list -> elems地址:00000000

请按任意键继续. . .

清空顺序表

代码语言:javascript
复制
// 清空顺序表
void ClearList(SeqList list){
	list -> len = 0;		// 将顺序表的长度置为 0
}

顺序表判空

代码语言:javascript
复制
// 顺序表判空
int ListEmpty(SeqList list){
	if(list == NULL) return FALSE;
	return list -> len == 0;
}

只需要判断顺序表的长度是否为0, 0则空反之有元素。

求顺序表的长度

代码语言:javascript
复制
// 获取顺序表的长度
int GetLen(SeqList list){
	return list -> len;
}

顺序表的遍历

代码语言:javascript
复制
// 遍历顺序表
void Travel(SeqList list){
	for(int i=0;i<list -> len;i++){
		printf("%d\t", list -> elems[i]);
	}
	printf("\n");
}

顺序表的插入​(重点)

顺序表的插入算法思想如下:

  1. 判断插入位置 pos 是否合法
  2. 判断顺序表的存储空间是否已满,若已满,返回 FALSE
  3. pos 位置之后的所有元素向后移动一位
  4. 将新元素插入到 pos 位置
  5. 顺序表长度len加1,此时插入成功,返回 TRUE

算法实现

代码语言:javascript
复制
/*
 * 指定位置在顺序表插入元素
 * pos 逻辑下标 (1, 2, 3, ...)
 * elem 要插入顺序表的元素
*/
int ListInsert(SeqList list, int pos, ElemType elem){
	// 判断插入位置是否合理
	if(pos <= 0 || pos > list -> len + 1){
		return FALSE;
	}

	// 判断顺序表是否已满
	if(list -> len == MAXSIZE){
		return FALSE;
	}

	// 元素后移
	for(int i=list -> len;i>= pos;i--){
		// 1 [2] 3 4 5
		list -> elems[i] = list -> elems[i-1];
	}

	// 元素插入
	list -> elems[pos - 1] = elem;
	list -> len ++;	// 记得更新顺序表长度
	return TRUE;
}

注意:元素后移是从顺序表最后一个元素开始移动

表尾插入

假设顺序表容量为6,MAXSIZE = 6

顺序表的长度为4,len = 4

在顺序表第5个位置插入元素5,pos = 5elem = 5

顺序表初始状态
顺序表初始状态
代码语言:javascript
复制
由于len < pos		--> 	4 <  5
所以for循环条件不满足
    
直接插入elems[pos - 1] = elem;	--> 	elems[4] = 5
顺序表表尾插入
顺序表表尾插入

表中插入

假设顺序表容量为6,MAXSIZE = 6

顺序表的长度为4,len = 4

在顺序表第2个位置插入元素5,pos = 2elem = 5

顺序表初始状态
顺序表初始状态

从顺序表最后一个元素开始移动后

元素后移后的顺序表
元素后移后的顺序表

移动过程

代码语言:javascript
复制
 1、elems[4] = elems[4 - 1];  -->	elems[4] = elems[3]
 2、elems[3] = elems[3 - 1];  --> 	elems[3] = elems[2]
 3、elems[2] = elems[2 - 1];  --> 	elems[2] = elems[1]

元素插入后

代码语言:javascript
复制
elems[pos - 1] = elem;	--> 	elems[1] = 5
元素插入后的顺序表
元素插入后的顺序表

顺序表的删除​(重点)

顺序表的删除算法思想如下:

  1. 判断删除位置 pos 是否合法
  2. 先把要删除元素的值保存起来
  3. pos 位置之后的所有元素向前移动一位
  4. 顺序表长度len减1,此时删除成功,返回 TRUE
代码语言:javascript
复制
/*
 * 指定位置在顺序表删除元素
 * pos 逻辑下标 (1, 2, 3, ...)
 * val 用来保存删除元素的值
*/
int ListDelete(SeqList list, int pos, ElemType *val){
	// 判断删除位置是否合法
	if(pos <= 0 || pos > list -> len){
		return FALSE;
	}

	*val = list -> elems[pos - 1];	// 先保存要删除元素的值

	// 元素前移
	for(int i=pos - 1;i<list -> len;i++){
		list -> elems[i] = list -> elems[i + 1];
	}

	list -> len --;	// 记得更新顺序表长度
	return FALSE;
}

假设顺序表容量为6,MAXSIZE = 6

顺序表的长度为4,len = 5

删除顺序表第2个位置的元素,pos = 2

顺序表的删除过程
顺序表的删除过程

元素向前移动过程

代码语言:javascript
复制
1、elems[1] = elems[1 + 1];	--> elems[1] = elems[2];
2、elems[2] = elems[2 + 1];	--> elems[2] = elems[3];
3、elems[3] = elems[3 + 1];	--> elems[3] = elems[4];

顺序表的查找​(重点)

查找指定位置的顺序表元素

代码语言:javascript
复制
/*
 * 查找指定位置的顺序表元素
 * pos 逻辑下标 (1, 2, 3, ...)查找的位置
 * val 用来保存元素的值
*/
int GetElem(SeqList list, int pos, ElemType *val){
	// 判断位置是否合理
	if(pos <= 0 || pos > list -> len){
		return FALSE;
	}
	*val = list -> elems[pos - 1];
	return TRUE;
}

查找顺序表指定元素的位置(第一个匹配成功的元素位置)

代码语言:javascript
复制
/*
 * 查找顺序表指定元素的位置(第一个匹配成功的元素位置)
 * elem 要查找的元素
 * pos 逻辑下标 (1, 2, 3, ...)用来保存元素的位置
*/			
int LocateElem(SeqList list, ElemType elem, int *pos){
	for(int i=0;i<list -> len;i++){
		if(list -> elems[i] == elem){	// 判断元素是否相等
			*pos = i + 1;				// 通过指针把逻辑下标返回
			return TRUE;
		}
	}
	return FALSE; 	// 没找到返回FAlSE
}	

源代码

源代码已上传到 GitHub Data-Structure-of-C,欢迎大家下载 C语言实现数据结构

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/06/11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 线性表的常规操作
  • 定义顺序表结构体
  • 初始化顺序表
  • 顺序表的销毁
  • 清空顺序表
  • 顺序表判空
  • 求顺序表的长度
  • 顺序表的遍历
  • 顺序表的插入​(重点)
    • 算法实现
      • 表尾插入
        • 表中插入
        • 顺序表的删除​(重点)
        • 顺序表的查找​(重点)
          • 查找指定位置的顺序表元素
            • 查找顺序表指定元素的位置(第一个匹配成功的元素位置)
            • 源代码
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档