数据结构复习——顺序表

数据结构复习——顺序表

知识点

  1. 线性表:具有相同数据类型的n( n ≥ 0 n\geq0 n0)个数据元素的有限序列。除第一个元素外,每个元素只有一个直接前驱;除最后一个元素外,每个元素只有一个直接后继;存在唯一的第一元素和最后元素。
  2. 线性表的基本操作:
    (1) 初始化initList(&L)
    (2) 求表长length(L)
    (3) 按值查找操作locateElem(L,e)
    (4) 按位查找操作getElem(L,i)
    (5) 插入操作listInsert(&L,i,e)
    (6) 删除操作listDelete(&L,i,&e)
    (7) 输出操作print(L)
    (8) 判空操作empty(L)
    (9) 销毁操作destoryList(&L)
  3. 顺序表(Sequential List):顺序存储的线性表
  4. 顺序表的结构:
数组下标顺序表内存地址
0 a 1 a_{1} a1loc(A)
1 a 2 a_{2} a2loc(A)+sizeof(ElemType)
i-1 a i a_{i} ailoc(A)+sizeof(ElemType)*(i-1)
  1. 创建顺序表的方法
#define SUCCESS 1
#define ERROR -1
#define Maxsize 50
typedef ElemType int;
typedef struct{
	ElemType data[Maxsize];//静态分配
	int length;//当前表的长度,没有数据元素时是0
}sqList;
#define initSize 100
typedef struct{
	ElemType *data;//动态分配
	int Maxsize, length;//最大长度和当前长度
}sqList;
L.data = (ElemType*)malloc(sizeof(ElemType)*initSize);
  1. 顺序表的特点
    (1)存取方式:随机存取(通过首地址或者序号可以在O(1) 内找到指定元素)
    (2)存储密度:(每个结点只存储数据元素)
    (3)物理位置:与逻辑位置相符,需要一段连续的存储空间,不利于扩展
    (4)操作:在删除、插入操作时需要移动大量元素
  2. 顺序表的插入
//i取0~L.length,即物理存储上的下标,非第几个
void listInsert(sqList &L,int i,ElemType e)
{
	if(i<0 || i>L.length)//如果插入位置非法(可插在末尾)
		return ERROR;
	for(int j = L.length;j > i;j--)//移动数据
	{
		L.data[j] = L.data[j-1];
	}
	L.data[i] = e;
	L.length ++;
	return SUCCESS;
}
/*
*最好情况:在最后插入,不移动元素
*最坏情况:在第一个位置插入,移动n个元素
*所有情况的移动次数之和:0+1+...+n=n(n+1)/2
*一共有n+1种情况,除以n+1,因此平均时间复杂度为T(n)=O(n/2)=O(n)
*/
  1. 顺序表的删除
void listDelete(sqList &L, int i , ElemType &e)
{
	if(i<0 || i > L.length-1)
		return ERROR;
	e = L.data[i];
	for(int j = i ; j < L.length-1 ; j++)
	{
		L.data[j] = L.data[j+1];
	}
	L.length --;
	return SUCCESS;
}
/*
*最好情况:删除最后一个,不移动元素
*最坏情况:删除第一个元素,移动n-1个元素
*所有情况的移动次数之和:0+1+...+n-1=n(n-1)/2
*一共有n种情况,除以n,因此平均时间复杂度为T(n)=O((n-1)/2)=O(n)
*/
  1. 顺序表的按值查找
int locateElem(sqList L, ElemType e)
{
	for(int i = 0;i < L.length;i++)
	{
		if(L.data[i] == e)
			return i;
	}
	return ERROR;
}
  1. 顺序表的按位查找
ElemType getElem(sqList L, int i)
{
   if(i < 0 || i > L.length-1)
   	retrun ERROR;
   return L.data[i];
}

11.扩展(合并两个有序顺序表)

int Merge(sqList A, sqList B, sqList &C)
{
	if(A.length + B.length > Maxsize)
		return ERROR;
	int ai = 0, bi = 0, ci = 0;
	while(ai < A.length && bi < B.length)
	{
		if(A.data[ai] > B.data[bi])
		{
			C.data[ci++] = B.data[bi++];
		}
		else
		{
			C.data[ci++] = A.data[ai++];
		}
	}
	while(ai < A.length)
	{
		C.data[ci++] = A.data[ai++];
	}
	while(bi < B.length)
	{
		C.data[ci++] = B.data[bi++];
	}
	C.length = A.length + B.length;
	return SUCCESS;
}

练习题

  1. (判断)线性表采用顺序存储结构表示时,必须占用一段连续的空间(✔)
  2. (单选)如果一个顺序表中第一个元素的存储地址是1000,每个元素占用4个存储单元,那么第6个元素的存储地址是(A)
    A 、 1020 B 、 1010 C 、 1016 D 、 1024 A、1020\qquad B、1010\qquad C、1016\qquad D、1024 A1020B1010C1016D1024
  3. (单选)当需要随机查找线性表的元素时,宜采用(C)作为存储结构
    A 、双向链表 B 、循环链表 C 、顺序表 D 、单链表 A、双向链表\qquad B、循环链表\qquad C、顺序表\qquad D、单链表 A、双向链表B、循环链表C、顺序表D、单链表
  4. (单选)在长度为n的顺序表的第i个位置插入一个元素( 0 ≤ i ≤ n 0\leq i \leq n 0in),元素的移动次数为(A)
    A 、 n − i + 1 B 、 n − i C 、 i D 、 i − 1 A、n-i+1\qquad B、n-i\qquad C、i\qquad D、i-1 Ani+1BniCiDi1
  5. (单选)设顺序线性表中有n个数据元素,则删除表中第i个元素需要移动(A)个元素
    A 、 n − i B 、 n − i − 1 C 、 n − i + 1 D 、 i A、n-i\qquad B、n-i-1\qquad C、n-i+1\qquad D、i AniBni1Cni+1Di
  6. 对于顺序存储的线性表,访问结点,增加、删除的时间复杂度为(C)
    A 、 O ( n ) O ( n ) B 、 O ( n ) O ( 1 ) C 、 O ( 1 ) O ( n ) D 、 O ( 1 ) O ( 1 ) A、O(n)O(n)\qquad B、O(n)O(1)\qquad C、O(1)O(n)\qquad D、O(1)O(1) AO(n)O(n)BO(n)O(1)CO(1)O(n)DO(1)O(1)
  7. (判断)线性表的特点是每一个元素都有一个前驱和后继(✘)
  8. (单选)线性表的顺序存储结构是一种(A)的存储结构
    A 、随机存取 B 、顺序存取 C 、索引存取 D 、散列存取 A、随机存取\qquad B、顺序存取\qquad C、索引存取\qquad D、散列存取 A、随机存取B、顺序存取C、索引存取D、散列存取
  9. (单选)下列(A)是顺序存储的优点
    A 、存储密度大 B 、插入运算方便 A、存储密度大\qquad B、插入运算方便 A、存储密度大B、插入运算方便
    C 、删除运算方便 D 、需要大片连续的存储空间 C、删除运算方便\qquad D、需要大片连续的存储空间 C、删除运算方便D、需要大片连续的存储空间
  10. (单选)两个有序顺序表分别具有n个元素和m个元素,且n<m,则将其合并成一个有序表,其最少的比较次数是(A)
    A 、 n B 、 m C 、 n − 1 D 、 m + n A、n\qquad B、m\qquad C、n-1\qquad D、m+n AnBmCn1Dm+n
  11. (判断)删除顺序表中第一个元素的时间复杂度是O(n)(✔)
  12. (单选)在n个结点的顺序表中,算法的时间复杂度是O(1)的是(A)
    A、访问第i个结点和求第i个结点的直接前驱
    B、在第i个结点后插入一个节点
    C、删除第i个结点
    D、将n个结点从小到大排序
  13. (单选)下面哪一个不是线性表的特性(D)
    A、除第一个元素之外,每个元素都有前驱
    B、除最后一个元素外,每个元素都有后继
    C、线性表是数据元素的有限序列
    D、线性表的长度时n,并且n不等于0
  14. (填空)二维数组A[10][20]按优先顺序存储,每个元素占四个存储单元,A[1][1]的存储地址是1000,A[5][6]的存储地址是(1340)
  15. (编程)已知长度为n的线性表采用顺序存储结构,写一个算法,删除线性表中所有值为x的元素。
//方法一:使用k记录等于x的个数
void del(sqList &L, ElemType x)
{
	int k = 0;
	for(int i = 0;i < L.length; i++)
	{
		if(L.data[i] == x)
		{
			k++;
		}
		else
		{
			L.data[i-k] = L.data[i];
		}
	}
	L.length = L.length-k;	
}
//方法二:使用k记录不等于x的个数
void del(sqList &L, ElemType x)
{
	int k = 0;
	for(int i = 0; i < L.length ; i++)
	{
		if(L.data[i] != x)
		{
			k++;
		}
		L.data[k] = L.data[i];
	}
	L.length = k;
}
  1. (编程)设计一个高效算法,将顺序表L所有元素逆置
int reverse(sqList &L)
{
	int head = 0, tail = L.length-1;
	while(head <tail)
	{
		ElemType temp = L.data[head];
		L.data[head] = L.data[tail];
		L.data[tail] = temp;
		head++;
		tail--;
	}
	return SUCCESS;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值