线性表的顺序存储结构及基本操作

学习书籍《大话数据结构》,自学完后,总结一下,以后也好复习 ,欢迎互相交流。

线性表的基本操作功能如下:

InitList(*L):          初始化操作,建立一个空的线性表L

ListEmpty(L):      若线性表为空,返回true,否则返回false

ClearList(*L):      将线性表清空

GetElem(L,i,*e) : 将线性表L中的第i个位置元素返回给e

LocateElem(L,e) : 在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在表中序号表示成功;否则,返回0表示失败     

ListInsert(*L,i,e):    在线性表L中的第i个位置插入新元素e

ListDelete(*L,i,*e):  删除线性表L中第i个位置元素,并用e返回其值

ListLength(L):          返回线性表L的元素个数
 

 对于不同的应用,线性表的基本操作不同,对于现实中更复杂的操作,完全可以用这些基本操作完成。

例如:要实现两个线性表集合的并,将结果存入集合C中。先将集合A插入集合C中,再循环B集合中的每个元素,判断集合A中是否存在,不存在,则插入C。具体实现本代码的void unionL(SqList *Lc, SqList Lb,SqList La);

          要实现两个线性表集合的交,将结果存入集合C中。分析略(和交集类似,就不写了),具体实现本代码void insertction(SqList La, SqList Lb, SqList *Lc);

代码如下(编译软件vs2013):
 

#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 30   /*存储空间初始分配量*/

typedef int Status;/*status是函数的类型,其值是函数结果状态代码,如OK等*/
typedef int ElemType;  /*ElemType类型根据实际情况而定,这里假设为int*/


//输出元素c
Status visit(ElemType c)
{
	printf("%d ", c);
	return OK;
}

//线性表的顺序存储结构
typedef struct                 
{
	ElemType data[MAXSIZE];//数组存储数据元素,最大值为MAXSIZE
	int length;           //线性表当前长度
}SqList;

//初始化顺序线性表
Status InitList(SqList *L)
{
	L->length = 0;
	return OK;
}

/*初始条件:顺序线性表L存在。操作结果:若L为空表,则返回FALSE,否则返回TRUE*/
Status ListEmpty(SqList L)
{
	if (L.length == 0)
		return FALSE;
	else
		return TRUE;
}

//初始条件:顺序线性表L已存在。操作结果:将L重置为空表
Status ClearList(SqList *L)
{
	L->length = 0;
	return OK;
}

//初始条件:顺序线性表L已存在。操作结果:返回线性表L元素个数
int ListLength(SqList L)
{
	return L.length;
}

/*初始条件:顺序线性表L已存在,1<=i<=ListLength(L)
  操作结果:用e返回L中第i个数据元素的值,注意i是指位置,第1个位置的数组是从0开始*/
Status GetElem(SqList L, int i, ElemType *e)
{
	if (L.length == 0 || i<1 || i>L.length)
		return ERROR;
	*e = L.data[i - 1];
	return OK;
}

/*初始条件:顺序线性表L已存在
   操作结果:返回L中第1个与e满足关系的数据元素的位序
    若这样的数据元素不存在,则返回值为0*/
int LocateElem(SqList L, ElemType e)
{
	int i;
	if (L.length)                 //顺序线性表L存在且不为空
	{
		for (i = 0; i < L.length;i++)
		if (L.data[i] == e)
			return i+1;
	}
	return 0;
}

/*初始条件:顺序线性表L已存在,1<=i<=ListLength(L)
   操作结果:在L中第i个位置之前插入新的数据元素e,L中的长度加1*/
Status ListInsert(SqList *L, int i, ElemType e)
{
	int k;
	if (L->length == MAXSIZE || i < 1 || i>L->length + 1) //L满或i小于1或大于最后一个位置+1
		return ERROR;
	else
	{
		if (i <= L->length)
		{
			for (k = L->length; k >= i; k--)
				L->data[k] = L->data[k - 1];
		}
		L->data[i - 1] = e;
		L->length++;
		return OK;
	}
}

/*初始条件:顺序线性表L已存在,1<=i<=ListLength(L)
操作结果:删除L的第i个元素,并用e返回其值,L的长度减1*/
Status ListDelete(SqList *L, int i, ElemType *e)
{
	int k;
	if (L->length == MAXSIZE || i < 1 || i>L->length) //L满或i小于1或大于最后一个位置
		return ERROR;
	*e = L->data[i - 1];  //用e保存要删除的元素
	if (i<L->length)
	for (k = i - 1; k < L->length-1; k++)
		L->data[k] = L->data[k + 1];
	L->length--;
	return OK;
}

/*初始条件:顺序线性表L已存在
  操作结果:依次对L中的每个元素输出*/
Status ListTraverse(SqList L)
{
	int i;
	for (i = 0; i < L.length; i++)
		visit(L.data[i]);
	printf("\n");
	return OK;
}

//实现两个线性表集合的并集操作
//将所有的线性表中元素不重复的存入Lc中
void unionL(SqList *Lc, SqList Lb,SqList La)
{
	int La_len, Lb_len,Lc_len, i,j;
	ElemType e;   //声明La与Lb相同的元素e
	La_len = ListLength(La);
	Lb_len = ListLength(Lb);
	ClearList(Lc);
	Lc_len = ListLength(*Lc);
	for (j = 1; j <= La_len; j++)
	{
		GetElem(La, j, &e);    //取La中第i个元素赋给e
		ListInsert(Lc, ++Lc_len, e); //插入
	}
	for (i = 1; i <= Lb_len; i++)
	{
		GetElem(Lb, i, &e);    //取Lb中第i个元素赋给e
		if (!LocateElem(*Lc, e)) //La中不存在和e相同数据元素
			ListInsert(Lc, ++Lc_len, e); //插入
	}
}

//实现两个集合的交集操作
//将所有的在线性表Lb中且在La中的数据元素插入到Lc中
void insertction(SqList La, SqList Lb, SqList *Lc)
{
	int La_len, Lb_len, Lc_len, i;
	ElemType e;
	La_len = ListLength(La);
	Lb_len = ListLength(Lb);
	ClearList(Lc);
	Lc_len = ListLength(*Lc);
	for (i = 1; i <= Lb_len; i++)
	{
		GetElem(Lb, i, &e);
		if (LocateElem(La,e))  //La中存在和e相同数据元素
			ListInsert(Lc, ++Lc_len, e); //插入
	}
}
int main()
{
	SqList L;
	ElemType e;
	Status i;
	int j, k;
	i = InitList(&L);
	printf("初始化L后:L.length=%d\n", L.length);
	for (j = 0; j < 8; j++)
		ListInsert(&L, 1, j);
	printf("L表头依次插入0--7:");
	ListTraverse(L);

	printf("L是否为空:(1否0是)%d\n", ListEmpty(L));
	ClearList(&L);
	printf("清空线性表L\n");
	printf("L是否为空:(1否0是)%d\n", ListEmpty(L));

	for (int j = 1; j <=10; j++)
	{
		ListInsert(&L, j, j-1);
	}
	printf("在L表中1--10位置输入0--9数字:");
	ListTraverse(L);
	GetElem(L, 3, &e);
	printf("输出L中第3个元素:%d\n",e );
	k = LocateElem(L, 3);
	if (k)
	printf("找出L中第一个3所在的位置:%d\n",k);
	else
	{
		printf("L中无此元素\n");
	}
	k = ListDelete(&L, 4, &e);
	if (k)
		printf("删除L中第4个元素值为: %d\n", e);
	else
		printf("删除失败\n");
	printf("输出L中所有的元素:");
	ListTraverse(L);;

	SqList Lb;
	SqList Lc;
	InitList(&Lc);
	InitList(&Lb);
	for (j = 0; j < 7; j++)
	{
		ListInsert(&Lb, j, j + 5);
	}
	printf("输出Lb中所有的元素:");
	ListTraverse(Lb);
	unionL(&Lc,L, Lb);
	printf("输出L和Lb标的并集:");
	ListTraverse(Lc);

	
	insertction(L, Lb, &Lc);
	printf("输出L和Lb标的交集:");
	ListTraverse(Lc);
	system("pause");
	return 0;
}

结果截图:

插入和删除的平均时间复杂度:O(n)

线性表顺序存储结构的优缺点:
优点: 1.无须为表示表中元素之间的逻辑关系而增加额外的存储空间

             2.可以快速地存取表中任一位置的元素

缺点: 1.插入和删除操作需要移动大量元素

             2.当线性表长度变化较大时,难以确定存储空间的容量

             3.造成存储空间的“碎片”

猜你喜欢

转载自blog.csdn.net/cai_niaocainiao/article/details/82931109