《软件技术基础》之《线性表》

线性表是最基础和最常用的一类数据结构,它表示的是线性结构。
逻辑结构:在线性结构中,数据元素之间存在着一对一的关系,其特点是数据元素之间按某种规定存在一个顺序关系。

线性表的分类:
在这里插入图片描述

线性表的定义

n个同类型数据元素的有限序列,记为:L=(a1,a2,…,ai,…,an)。
其中,L为表名,i为数据元素ai在线性表中的位序,n为线性表的表长,n=0时称为空表。

数据元素之间的关系:
ai-1领先于ai ,ai领先于ai+1 。称ai-1是ai的直接前驱,ai+1是ai的直接后继
除第一元素a1外,均有唯一的前驱;除最后元素an外,均有唯一的后继。

线性表数据结构的定义

数据结构的一般定义:Data Structure=(D,L,S,O)

D=data(数据) L=logic(逻辑)S=storage(物理存储)O=operation(基本操作)

O是在逻辑结构上对数据结构或数据元素的一组基本运算,与具体实现无关,可以利用给定的基本操作构造更复杂的运算。

线性数据结构的存储结构

顺序存储结构

用一组地址连续的存储单元依次存放线性表中的数据元素。
在这里插入图片描述
以“存储位置相邻”表示有序对<ai-1,ai>,即:LOC(ai)=LOC(ai-1)+d。d是一个一个数据元素所占的存储单位长度,用物理地址的相邻关系来表示逻辑次序的相邻。
在这里插入图片描述
实现实例(C语言描述):

#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
Typedef struct Sqlist {
	ElemType *elem; // 存储地址基址
	int length; // 当前长度
	int listzise; // 当前分配的存储容量
}Sqlist; //顺序表

插入元素操作
步骤:

  1. 检查插入位置是否合法,如果合法则继续,否则退出;
  2. 判表是否已占满;因为事先静态地分配空间,可能存在所分配存储空间全部被占用的情况,此时也不能实现插入;
  3. 若前面检查通过则数据元素依次向后移动一个位置;为避免覆盖原数据,应从最后一个开始向前依次移动;
  4. 新数据元素放到恰当位置;
  5. 表长加 1。
    在这里插入图片描述
    算法实现:
Status List_Insert(ListPtr L,int pos,ElemType elem)
{
	Status status=range_error;
	int len=L->length,i;
	if(len == MAXSIZE) status=overflow;
	else if(1<=pos && pos<=len+1)
	{
		for(i=len;i>=pos;i--) L->elem[i+1]=L->elem[i]; // 数据后移一个位置
		L->elem[pos]=elem;
		L->length++;
		status=success;
	}
	return status;
}

删除元素操作
步骤:

  1. 检查删除位置是否合法;
  2. 若检查通过,数据元素依次向前移动一个位置;
  3. 表长减1。

在这里插入图片描述
算法实现:

Status List_Remove(ListPtr L,int pos)
{
	Status status=range_error;
	int len=L->length,i;
	if(1<=pos && pos<=len)
	{
		for(i=pos;i<len;i++) L->elem[i]=L->elem[i+1]; // 数据前移一个位置
		L->length--;
		status=success;
	}
	return status;
}

链式存储结构(单链表)

用一组地址任意的存储单元存放线性表中的数据元素。
数据域(数据元素)+指针域(指示后继元素存储位置)= 结点
以“结点的序列”表示线性表,称为链表。

逻辑结构:(a1,a2,…,ai,…,an)

物理结构
在这里插入图片描述
以线性表中第一个数据元素a1的存储地址作为线性表的地址,称为线性表的头指针
有时为了操作方便,在第一个结点之前虚加一个“头结点”,并用链表的头指针指向头结点,称为带头结点的单链表。
在这里插入图片描述
类型定义

typedef struct node {
	ElemType data; // 数据域
	struct node *next; // 指针域
}ListNode,*ListNodePtr;
typedef ListNodePtr List,*ListPtr;

变量定义和使用

ListNode n1,n2; // 定义两个结点变量
ListNodePtr p=&n1; // 定义一个指向结点的指针变量p,并存放n1的地址(指针)
n1.nest=&n2; // 结点n1的指针域存放结点n2的地址
List L; // 定义一个单链表L

在单链表中获取第pos个元素

ListNode List_Retrieve(ListPtr L,int pos)
{
	if(pos < 0) return null;
	if(pos == 0) return L;
	ListNode *node=L;
	int i=0;
	while(node && i<pos)
	{
		node=node->next;
		i++;
	}
	if(node == null) return null;
	return node;
}

插入操作
步骤:

  1. 找到ai-1的位置;
  2. 构造一个数据域为elem的新结点;
  3. 将其挂在单链表上。

在这里插入图片描述
算法实现:

Status List_Insert(ListPtr L,int pos,ElemType elem)
{
	Status status;
	ListNodePtr pre,s;
	status=List_SetPosition(L,pos-1,&pre); // 找到插入位置的前驱
	if(status == success)
	{
		s=(ListNodePtr)malloc(sizeof(ListNode));
		if(s)
		{
			s->data=elem;
			s->next=pre->next;
			pre->next=s;
		}
		else status=fatal;
	}
	return status;
}

删除操作
步骤:

  1. 求得ai-1的指针p;
  2. 修改ai-1的后继域为ai+1的地址;
  3. 释放第pos个结点所占的存储空间。

在这里插入图片描述
算法实现:

Status List_Remove(ListPtr L,int pos)
{
	Status status=range_error;
	ListNodePtr pre,q;
	status=List_SetPosition(L,pos-1,&pre); // 找到插入位置的前驱
	if(status == success)
	{
		q=pre->next;
		pre->next=q->next;
		free(q);
	}
	return status;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值