线性表(一)—— 顺序表

线性表(一)—— 顺序表


定义

顺序表 是在计算机内存中以数组的形式保存的线性表;
线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。
采用顺序存储结构的线性表通常称为顺序表。
顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。

顺序表的存储特点是:只要确定了起始位置,表中任一元素的地址都通过下列公式得到: LOC(ai)=LOC(a1)+(i-1)*L  1≤i≤n
其中,L是元素占用存储单元的长度。

优缺点

优点:

  1. 无需为表示表中元素的逻辑关系而增加额外的存储空间
  2. 可以快速地存取表中任意位置的元素

缺点:

  1. 插入和删除需要移动大量的元素
  2. 当顺序表长度变化较大时,难以确定存储空间的容量
  3. 造成存储空间的碎片

算法复杂度

  1. 线性表存读数据的时候,时间复杂度都是O(1)
  2. 插入、删除的时间复杂度都是O(n)
    说明顺序表比较适合元素个数不不大变化,而更多的是存取数据的应用。

具体操作

1.顺序表的结构定义:

#define maxlen 50        //定义顺序表中元素个数最多有几个
typedef struct{
	elementtype data[maxlen];     //elementtype是元素的类型 依具体情况而定
	int listlen;      //便于时刻了解顺序表里元素的个数
}seqlist; //顺序表的名称 不妨为seqlist

声明顺序表类型变量:
seqlist L,L1;

如顺序表的每个结点占用len个内存单元,用location (ki)表示顺序表中第i个结点ki所占内存空间的第1个单元的地址。则有如下的关系:
location (ki+1) = location (ki) +len location (ki) = location(k1) + (i-1)len
存储结构要体现数据的逻辑结构,顺序表的存储结构中,内存中物理地址相邻的结点一定具有顺序表中的逻辑关系。

2.具体程序实现

/*----------------------------------------------------------------------------------------

	程序说明:顺序表
	创建日期:2019.9.14 by YanFei
----------------------------------------------------------------------------------------*/
#include 
#include 

/* 数组长度及顺序表的初始化长度 */
#define MAX_SIZE 10
#define LEN 	 5

/* 数据元素类型 */
typedef int SqType;

/* 顺序表的结构定义 */
typedef struct Sqlist
{
	SqType elem[MAX_SIZE];  // 存放顺序表元素的数组
	int length;				// 顺序表的长度
}Sqlist;

//函数的声明
Sqlist create_list(void);										// 初始化顺序表
void printf_list(Sqlist l);										// 打印顺序表
int serch(Sqlist l, SqType elem);   							// 查找元素位置	
Sqlist replace_elem(Sqlist l, SqType old_elem, SqType new_elem);// 替换旧元素old_elem为新元素new_elem
Sqlist replace_pos(Sqlist l, int pos, SqType elem);				// 替换位置pos上的元素为elem
Sqlist insert(Sqlist l, int pos, SqType elem);					// 插入新元素
Sqlist delete(Sqlist l, int pos);								// 删除元素

int list[LEN] = { 5, 2, 0, 13, 14 };	// 用于初始化顺序表

/*******************************************************************************************************
** 函数: main,主函数
**------------------------------------------------------------------------------------------------------
** 参数: void
** 返回: 无
** 日期: 2019.9.14 by YanFei
********************************************************************************************************/
int main(void)
{
	Sqlist l;
	int pos = 0;
	int serch_elem = 13;

	/* 创建一个顺序表:(5, 2, 0, 13, 14) */
	l = create_list();
	printf("创建的顺序表为:");
	printf_list(l);		// 打印输出顺序表

	/* 把旧元素0替换为新元素1 */
	l = replace_elem(l, 0, 1);
	printf("把0替换为1得到的新顺序表为:");
	printf_list(l);

	/* 把第1个位置上的元素改为10 */
	l = replace_pos(l, 1, 10);
	printf("第一个位置改为10得到的新顺序表为:");
	printf_list(l);

	/* 往第二个位置插入新元素99 */
	l = insert(l, 2, 99);
	printf("第二个位置插入99得到的新顺序表为:");
	printf_list(l);

	/* 删除第二个位置上的元素 */
	l = delete(l, 2);
	printf("删除第二个位置元素得到的新顺序表为:");
	printf_list(l);

	pos = serch(l, serch_elem); // 查找serch_elem在该顺序表l中的第几个位置
	printf("元素%d在顺序表的第%d个位置\n", serch_elem, pos);

	return 0;
}

/*******************************************************************************************************
** 函数: create_list,创建一个顺序表
**------------------------------------------------------------------------------------------------------
** 参数: void
** 返回: 创建成功的顺序表
** 日期: 2019.9.14 by YanFei
********************************************************************************************************/
Sqlist create_list(void)
{
	Sqlist l;

	for (int i = 0; i < LEN; i++)
	{
		l.elem[i] = list[i];
	}
	l.length = LEN; // 顺序表长度

	return l;	// 创建成功的顺序表
}

/*******************************************************************************************************
** 函数: serch,查找元素elem在顺序表l的第几个位置
**------------------------------------------------------------------------------------------------------
** 参数: l:顺序表   elem:要查找的元素
** 返回: pos:元素elem的位置  -1:查找失败
** 日期: 2019.9.14 by YanFei
********************************************************************************************************/
int serch(Sqlist l, SqType elem)
{
	int i;
	int pos = 0;
	for (i = 0; i < l.length; i++)
	{
		if (elem == l.elem[i])
		{
			pos = i + 1;
			return pos;
		}
	}

	return -1;	//查找失败
}

/*******************************************************************************************************
** 函数: replace_elem,把旧元素old_elem替换为新元素new_elem
**------------------------------------------------------------------------------------------------------
** 参数: l:顺序表  old_elem:旧元素  new_elem:新元素
** 返回: 替换完成后的新的顺序表l
** 日期: 2019.9.14 by YanFei
********************************************************************************************************/
Sqlist replace_elem(Sqlist l, SqType old_elem, SqType new_elem)
{
	int old_elem_pos;

	old_elem_pos = serch(l, old_elem);	// 首先查找旧元素所在的位置
	l.elem[old_elem_pos - 1] = new_elem;

	return l;   // 返回新生成的顺序表
}

/*******************************************************************************************************
** 函数: replace_pos,把第pos个位置上的元素替换为elem
**------------------------------------------------------------------------------------------------------
** 参数: l:顺序表  pos:位置  elem:元素
** 返回: 替换完成后的新的顺序表l
** 日期: 2019.9.14 by YanFei
********************************************************************************************************/
Sqlist replace_pos(Sqlist l, int pos, SqType elem)
{
	l.elem[pos - 1] = elem;

	return l; // 返回新生成的顺序表
}

/*******************************************************************************************************
** 函数: insert,把元素elem插入到顺序表l的第pos个位置
**------------------------------------------------------------------------------------------------------
** 参数: l:顺序表  pos:位置  elem:元素
** 返回: 插入元素后得到的新的顺序表l
** 日期: 2019.9.14 by YanFei
********************************************************************************************************/
Sqlist insert(Sqlist l, int pos, SqType elem)
{
	int i;
	/* 插入的位置不存在或则表长已经达到顺序表的最大允许值 */
	if (pos < 0 || pos > l.length || l.length >= MAX_SIZE)
	{
		printf("%s:插入错误!\n", __FUNCTION__);
		return l;
	}

	l.length += 1;	// 插入新元素,表长加一

	/* 从第pos个位置开始所有元素往后移一个元素长度 */
	for (i = l.length - 1; i >= pos - 1; i--)
	{
		l.elem[i + 1] = l.elem[i];
	}

	l.elem[pos - 1] = elem;	// 插入的新元素

	return l;  // 返回新生成的顺序表
}

/*******************************************************************************************************
** 函数: delete,把第pos个位置的元素删除
**------------------------------------------------------------------------------------------------------
** 参数: l:顺序表  pos:位置
** 返回: 删除元素后得到的新的顺序表l
** 日期: 2019.9.14 by YanFei
********************************************************************************************************/
Sqlist delete(Sqlist l, int pos)
{
	int i;
	/* 要删除的位置不存在 */
	if (pos < 0 || pos > l.length)
	{
		printf("%s:删除错误!\n", __FUNCTION__);
		return l;
	}

	/* 从第pos个位置开始所有元素前移一个元素长度 */
	for (i = pos - 1; i < l.length - 1; i++)
	{
		l.elem[i] = l.elem[i + 1];
	}
	l.length -= 1;	// 删除一个元素后表长减一

	return l;  // 返回新生成的顺序表
}

/*******************************************************************************************************
** 函数: printf_list,打印输出顺序表
**------------------------------------------------------------------------------------------------------
** 参数: l:顺序表  pos:位置
** 返回: 删除元素后得到的新的顺序表l
** 日期: 2019.9.14 by YanFei
********************************************************************************************************/
void printf_list(Sqlist l)
{
	int i;
	for (i = 0; i < l.length; i++)
	{
		printf("%d ", l.elem[i]);
	}
	printf("(表长为%d)", l.length);
	printf("\n\n");
}

你可能感兴趣的:(线性表(一)—— 顺序表)