线性表实验报告

线性表

基本概念

线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。数据元素是一个抽象的符号,其具体含义在不同的情况下一般不同。
在稍复杂的线性表中,一个数据元素可由多个数据项(item)组成,此种情况下常把数据元素称为记录(record),含有大量记录的线性表又称文件(file)。
线性表中的个数n定义为线性表的长度,n=0时称为空表。在非空表中每个数据元素都有一个确定的位置,如用ai表示数据元素,则i称为数据元素ai在线性表中的位序。
线性表的相邻元素之间存在着序偶关系。如用(a1,…,ai-1,ai,ai+1,…,an)表示一个顺序表,则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。当i=1,2,…,n-1时,ai有且仅有一个直接后继,当i=2,3,…,n时,ai有且仅有一个直接前驱 [1] 。

常用的线性表(我所知)

1、数组

数组在实际的物理内存上也是连续存储的,数组有上界和下界, 定义一个数组:

在这里插入图片描述
数组下标是从0开始的,a[0]对应第一个元素。其中,a[0]称为数组a的下界,a[6]称为数组a的上界。超过这个范围的下标使用数组,将造成数组越界错误。

特点

C语言中数组分为俩种,第一种是固定数组,这种数组在定义数组时就需要确定数组大小,第二种数组时动态数组,动态数组允许在运行时申请数组内存。(通过malloc来分配动态数组)

优点

1.无需为表示线性表中的逻辑关系而增加额外的存储空间。
2.可以快速的访问线性表中任一位置的元素。

缺点

1.插入和删除操作需要移动大量的元素。

2.难以确定线性表存储空间的容量。

3.造成存储空间的“碎片”,浪费存储空间。

代码:
动态分配数组
typedef int DataType
DataType *a;
int n;
scanf("%d",&n);//n是自己输入的动态数组的大小
a=(DataType*)malloc(sizeof(DataType)*n);//分配

2、链表

1)单向链表

单向链表是链表的一种。链表由节点所构成,节点内含一个指向下一个节点的指针,节点依次链接成为链表。因此,链表这种数据结构通常在物理内存上是不连续的。链表的通常含有一个头节点,头节点不存放实际的值,它含有一个指针,指向存放元素的第一个节点。
  其节点包含
  1.数据域:存贮该节点表示的元素的各种信息。
  2.指针域:指向下一个节点的指针。
  在这里插入图片描述

代码:
(1)链表结构:
typedef struct node
{
    int data;
    node *next;
}LNode,*LinkList;//Lnode是node的别名,LinkList是node*的别名
(2)创建链表(含头结点):
LinkList Creat()
{
	LinkList list;
	list = (LinkList)malloc(sizeof(LNode));
	if (list == NULL)//创建头节点失败
	{
		printf("Error!\n");
		return NULL;
	}
	return list;
}
(3)查找
bool Find(LinkList head, int data)//list 为传下来的链表 data为要查找的节点的data
{
	LinkList list = head;
	while (list != NULL)
	{
		if (list->data == data)
		{
			return true;
		}
		else
		{
			list = list->next;
		}
	}
	return false;
}
(4)节点个数
int NodeNum(LinkList head)
{
	LinkList list = head;
	int count=0;//计数
	while (list != NULL)
	{
		count++;
		list = list->next;
	}
	return count;
}
(5)插入节点(头插法与尾插法)

在这里插入图片描述

LinkList InsertTailNode(LinkList head,int x)//尾插法
{
	LinkList list = head;
	if (head == NULL)
	{
		return NULL;
	}
	while (list->next != NULL)//找到插入位置(链表尾部)
	{
		list = list->next;
	}
	LinkList NewNode = (LinkList)malloc(sizeof(LNode));
	NewNode->next = NULL;
	NewNode->data = x;
	list->next = NewNode;
	return head;
}
LinkList InsertHeadNode(LinkList head, int x)//头插法
{
	LinkList list = head;
	if (head == NULL)
	{
		return NULL;
	}
	LinkList NewNode = (LinkList)malloc(sizeof(LNode));
	NewNode->next = NULL;
	NewNode->data = x;
	if (list->next == NULL)
	{
		list->next = NewNode;
		//return head;
	}
	else
	{
		NewNode->next = list->next;
		list->next = NewNode;
	}
	return head;

}


(6)删除链表

在这里插入图片描述

bool DeleteNode(LinkList head, int x)
{
	LinkList cur=head->next,pre=head;
	if (cur||pre)
	{
		return false;
	}
	while (cur)
	{
		if (cur->data == x)
		{
			pre->next = cur->next;
			free(cur);
			return true;
		}
		else
		{
			pre = cur;//pre=pre->next;
			cur = cur->next;
		}
	}
	return false;
}
2、单向链表结构与顺序存储结构的优缺点
1. 顺序存储结构用一段连续的存储单元依次存储线性表的数据元素。

2.查找:顺序存储结构O(1),单链表O(n)。

3.插入和删除:顺序存储结构O(n),单链表O(1)。

4.顺序存储结构需要预先分配存储空间,分大了浪费空间,分小了容易造成内存溢出;单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制。
2)循环链表

将单链表中终端节点的指针由空指针改为指向头节点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环列表,简称循环列表(circular linked list)。循环列表解决了一个很麻烦的问题:如何从任意一个节点出发,访问到链表的全部节点。

在这里插入图片描述

其实循环列表和单链表的主要差异就在于循环的判断条件上,单链表是判断p->next是否为空,现在则是p->next不等于头结点,则循环未结束。

队列

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wy-1226

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

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

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

打赏作者

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

抵扣说明:

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

余额充值