顺序表的插入、删除代码分析笔记


前言:以下内容为个人理解和笔记,如有错误之处,还请指正。感谢!

顺序表

定义

1、把线性表的结点,按逻辑顺序依次存放在一组地址连续的存储单元里(一大块连续的存储空间)。
2、如果顺序表的首地址为L0,其中每个元素占m个字节,那么第i个元素的存储地址为 L0+ (i-1)*m。

特点

1、元素结点在逻辑上相邻,在物理存储上也相邻。
2、通过位置(下标)可以实现“随机存取”(直接存、取第i个元素,时间复杂度为O(1))。

代码

结构体定义

代码:

#define MAXSIZE 100
typedef int ElemType;
typedef struct {
    ElemType *elem;    //定义为指针,用new创建时,即表示存储空间的首地址
    int length;    //顺序表当前长度
}SqList;    //定义顺序表的别名

1、个人理解为此处做了两件事,一是定义了一个结构体,而是给这个结构体起了一个别名为SqList

初始化

代码:

//C语言实现
bool InitList(SqList *L){
    L->elem = (ElemType*)malloc(MAXSIZE*sizeof(ElemType));
    //开辟100*4=400个存储单元(字节)
    if(!L->elem){
        //exit函数的参数为0,表示正常执行程序并退出程序。不为0表示异常退出。
        exit(0);
    }
    L->length = 0;
    return true;
}

个人理解,malloc函数前的(ElemType*)的意思是转化为ElemType类型的指针,因为“C语言中malloc返回一个指向已分配空间的 void指针,若要返回指向非 void类型的指针,请在返回值上使用类型转换。”来自c语言中malloc的返回值
代码:

//C++实现
bool InitList(SqList *L){ 
    L->elem = new ElemType[MAXSIZE];
    if(!L->elem){
        exit(0);
    }
    L->length = 0;
    return true;
}

插入

代码:

void InsertList(SqList &L,int i,ElemType e){
	//i为逻辑插入位置
    if(i < 1 || i > L.length+1){  
        printf("Position error!");
        return ;
    }
    if(L.length == L.ListSize){
        cout << "overflow";
        //EXIT_FAILURE值为1,exit(1)表示非正常执行导致退出程序。
        exit(EXIT_FAILURE);
    }
    for(int j = L.length - 1; j >= i - 1; j--){
        L.elem[j+1] = L.elem[j];
    }
    L.elem[i-1] = e;
    L.length++;
    return;
}

1、逻辑插入位置,不能小于1(物理为不能小于0)、不能大于length+1(物理为不能大于最后一个元素后面的位置,因为中间不能空一格)。
2、插入时,下标问题。要想在逻辑位置为i(物理位置为i-1) 的地方插入元素,就必须将物理上第i-1个元素(及其后面的每个元素)往后移,因此,必须从后往前挨个往后移动,挪出一个位置来插入元素。
第一种情况
jL.length-1开始,即L. elem[j]为最后一个元素。j 往前移动,使得每个元素往后移动的话,就得是L.elem[j+1] = L.elem[j]。要想将第i-1个元素移动的话,j就得等于 i-1,这样才能将第 i-1个位置上的元素往后移动一格。
即:

for(int j = L.length-1; j >= i-1; i--)
	L.elem[j+1] = L.elem[j];

第二种情况
jL.length开始,即L.elem[j-1]为最后一个元素。j往前移动,使每个元素往后移动,则是L.elem[j] = L.elem[j-1]。要想将第i-1个元素往后移动的话,那么j就得等于i,这样才能将第i-1个位置上的元素往后移动一格。
即:

for(int j = L.length; j >= i; j--)
	L.elem[j] = L.elem[j-1];

删除

代码:

void DeleteList(SqList &L,int i,ElemType &e){
    if(i < 1 || i > L.length){
        printf("Position error!");
        return ;
    }
    if(L.length == 0){
        cout << "error!No elements!";
        exit(1);
    }
    e = L.elem[i-1];
    //j从i-1(要删除的那个数)开始,将j+1中的元素向前(j)移一格,j+1最多只能为L.length-1(若j=L.length-1,j+1=L.length,那就越界了),所以是j<L.length-2(很别扭,不要用)
    //应该j从i(要删除的数的后面的数)开始,将j中的元素向前(j-1)移一格,则j最多只能为L.length-1,所以应该是j<L.length
    for(int j = i; j < L.length-1; j++){
        L.elem[j-1] = L.elem[j];
    }
    L.length--;
    return;
}

1、逻辑位置不能小于1(物理位置不能小于0)、不能大于L.length(最多只能删除最后一个元素)。
2、要求将第i个(物理位置为i-1)元素删除,并用变量记录该值。删除物理上第i-1个元素,可以直接将第i个位置上的元素前移,将其覆盖,其后所有元素都依次(从前往后的顺序)前移,顺序表的长度再-1,即表示删除了第i-1个元素。
第一种情况:
ji开始,即L.elem[j-1]才是要删除的元素,要想将其删除并将其后所有元素前移,则应该是L.elem[j-1] = L.elem[j],但j最大只能是L.length-1(最大下标)。
即:

for(int j = i; j <= L.length-1; j++){
        L.elem[j-1] = L.elem[j];
    }

第二种情况:
ji-1开始,即L.elem[j]就是要删除的元素,即L.elem[j] = L.elem[j+1],即可将元素前移,但j+1最大只能是L.length-1(最大下标),即j不能大于L.length-1,即j最大只能是L.length-2
即:

for(int j = i-1; j <= L.length-2; j++) //或者写j < L.length-1
	L.elem[j] = L.elem[j+1];

其余的函数,比如获取某个位置的元素、查找某个元素的位置都好理解,就不做记录了。下面就再多搞一个排序吧。

顺序表元素排序

代码:

//这里采用冒泡法,快速排序忘了怎么搞了。。。
void SortList(SqList &L){
	int tmp;
	for(int i = 0; i < L.length-1; i++)
		for(int j = 0; j < L.length-i-1; j++)
			if(L.elem[j] > L.elem[j+1]){
				tmp = L.elem[j];
				L.elem[j] = L.elem[j+1];
				L.elem[j+1] = tmp;
			}
}

大概以上就是关于顺序表中个人感觉不太好理解的内容了,欢迎大家指正!谢谢!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

万宝炉

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

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

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

打赏作者

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

抵扣说明:

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

余额充值