【顺序表】知识点(含代码实现)
创始人
2024-01-15 09:07:06
0

文章目录

1、概念

2、存储结构

3、数据长度和线性表长度的区别

4、顺序表的操作

初始化

 判断表满

判空

输出

插入

查找

删除pos位置的值

删除第一个val的值

返回key结点的前驱

返回key结点的后继

清空数据

销毁顺序表

5、完整代码

6、顺序表的优缺点


概念

顺序表:线性表的顺序存储

存储结构

存储空间的起始位置:数组elem,他的存储位置就是存储空间的存储位置。

线性表的最大存储容量:数组长度MaxSize

线性表的当前长度:length

#define MAXSIZE 20typedef struct SQList
{int elem[10];//数组int length;//长度
}SQList,*PSQList;

数据长度和线性表长度的区别

  • 数组的长度是存放线性表的存储空间的长度,存储分配后诸葛亮一般是不变化的。但是可以用变成手段实现动态分配内存。
  • 线性表的长度是线性表中数据元素的个数。随着线性表插入和删除操作的进行,这个量时是变化的,因此在代码实现时对表进行插入和删除时一定要记得对链表长度leng进行修改。
  • 在任意时刻,线性表的长度应该小于等于数组长度。

顺序表的操作

前言:

本例在实现过程中,数组下标均为从0开始。

初始化

void InitSqlist(PSQList ps)
{assert(ps!=NULL);if(ps==NULL){return;}ps->length=0;
}

 判断表满

static bool IsFull(PSQList ps)
{return ps->length ==MAXSIZE; //如果满足,返回为true
}

判空

bool IsEmpty(PSQlist ps)
{assert(ps!=NULL)if(ps==NULL)return flase;//空表return ps->length==0;
}

输出

void Show(PSQlist ps)
{assert(ps!=NULL);if(ps==NULL)return;for(int i=0;ilength;i++){printf("%d",ps->elem[i]);}printf("\n");
}

插入

思想

  1. 表为空表,返回flase
  2. 表满,返回flase
  3. 如果插入位置不合理,返回flase
    1. 不能在下标<0位置插入
    2. 不能在>=数组长度(越界)的位置插入。
  4. 如果线性表的长度大于数组长度,返回flase
  5. 从最后一个元素开始向前遍历到第pos个位置,分别将他们都向后移动一个位置
  6. 将要插入的元素填入位置pos处
  7. 表长+1

代码实现

bool  Insert(PSQList ps, int pos, int val)
{assert(ps!=NULL);if(ps==NULL)//判断参数return flase;if(pos<0||pos>ps->length)//没有等号return flase;/*if(ps->length==MAXSIZE)return flase;*/ //可以调用IsFull函数if(IsFull(ps)return flase;//把数据移到后面for(int i=ps->length-1;i>=pos;i--){ps->lelem[i+1]=ps->elem[i];}//插入数据ps->elem[pos]=val;//有效数据个数+1ps->length++;//这个易忘return true;
}

查找

实现在ps查找第一个key值,找到返回下标,没找到返回-1

代码实现

int  Search(PSQList ps, int key)
{assert(ps != NULL);//判断参数if (ps == NULL){return  -1;}for (int i = 0; i < ps->length; i++){if (key == ps->elem[i]){return i;//找到了}}//没找到return -1;
}

删除pos位置的值

思路

  1. 如果删除位置不合适,返回false
    1. 不能在下标<0位置插入
    2. 不能在>=数组长度(越界)的位置插入。
  2. 从删除位置pos开始遍历到最后一个元素位置,分别将她们都向前移动到pos位置
  3. 表长-1

代码

bool  DelPos(PSQList ps, int pos)
{assert(ps != NULL);if (ps == NULL){return false;}if (pos < 0 || pos >= ps->length)//判断位置{return false;}//将后面的数据前移for (int i = pos; i < ps->length - 1; i++){ps->elem[i] = ps->elem[i + 1];}//有效数据个数--ps->length--;return true;
}

删除第一个val的值

思路

结合上面查找和删除第一个pos位置的值的代码。

  1. 查找到val的位置,对返回值进行判断知否合法,不合法返回flase1
  2. 调用删除函数

代码

bool  DelVal(PSQList ps, int val)
{int i = Search(ps, val);if (i < 0){return false;}return DelPos(ps, i);
}

返回key结点的前驱

思路

结合上面查找代码

  1. 查找到key的位置,对返回值进行判断知否合法,不合法返回flase1
  2. 如果值合法,返回-1就行(查找返回的是下标,前驱-1)

代码

int  GetPrio(PSQList ps, int key)
{int i = Search(ps, key);if (i <= 0)//注意,头没有前驱;{return -1;}return i - 1;
}

返回key结点的后继

思路

与返回前驱相似,结合上面查找代码

  1. 查找到key的位置,对返回值进行判断知否合法,不合法返回flase1
  2. 如果值合法,返回+1就行(查找返回的是下标,前驱+1)

代码

int  GetNext(PSQList ps, int key)
{int i = Search(ps, key);if (i < 0 || i == ps->length - 1)//注意,尾没有后继{return -1;}return i + 1;
}

清空数据

void  Clear(PSQList ps)
{ps->length = 0;
}

销毁顺序表

void  Destroy(PSQList ps)
{Clear(ps);
}

完整代码

sqlist.h

typedef struct SQList
{int elem[10];int length;
}SQList,*PSQList;//PSQList ==SQList *//初始化
void   InitSqlist(PSQList ps);//插入数据,在ps顺序表的pos位置插入val;
bool  Insert(PSQList ps, int pos, int val);//判空
bool   IsEmpty(PSQList ps);//在ps查找第一个key值,找到返回下标,没有找到返回-1;
int  Search(PSQList ps, int key);//删除pos位置的值
bool  DelPos(PSQList ps, int pos);//删除第一个val的值
bool  DelVal(PSQList ps, int val);//返回key的前驱下标,如果不存在返回-1;
int  GetPrio(PSQList ps, int key);//返回key的后继下标,如果不存在返回-1;
int  GetNext(PSQList ps, int key);//输出
void  Show(PSQList ps);//清空数据
void  Clear(PSQList ps);//销毁整个内存
void  Destroy(PSQList ps);

sqlist.cpp

#include  "sqlist.h"
#include 
#include 
//定长顺序表;
//初始化
void   InitSqlist(PSQList ps)
{assert(ps != NULL);if (ps == NULL){return;}ps->length = 0;
}
//判满
static bool IsFul(PSQList ps)
{return ps->length == 10;
}
//插入数据,在ps顺序表的pos位置插入val;
bool  Insert(PSQList ps, int pos, int val)
{assert(ps != NULL);if (ps == NULL){return   false;}if (pos<0 || pos>ps->length  ||IsFul(ps)){return false;}//把数据移动到后面for (int i = ps->length - 1; i >= pos; i--){ps->elem[i + 1] = ps->elem[i];}//插入数据ps->elem[pos] = val;//有效数据个数++;ps->length++;return true;
}//判空
bool   IsEmpty(PSQList ps)
{assert(ps != NULL);if (ps == NULL){return  false;}return ps->length == 0;
}//在ps查找第一个key值,找到返回下标,没有找到返回-1;
int  Search(PSQList ps, int key)
{assert(ps != NULL);if (ps == NULL){return  -1;}for (int i = 0; i < ps->length; i++){if (key == ps->elem[i]){return i;}}return -1;
}//删除pos位置的值
bool  DelPos(PSQList ps, int pos)
{assert(ps != NULL);if (ps == NULL){return false;}if (pos < 0 || pos >= ps->length){return false;}//将后面的数据前移for (int i = pos; i < ps->length - 1; i++){ps->elem[i] = ps->elem[i + 1];}//有效数据个数--ps->length--;return true;
}//删除第一个val的值
bool  DelVal(PSQList ps, int val)
{int i = Search(ps, val);if (i < 0){return false;}return DelPos(ps, i);
}//返回key的前驱下标,如果不存在返回-1;
int  GetPrio(PSQList ps, int key)
{int i = Search(ps, key);if (i <= 0)//注意,头没有前驱;{return -1;}return i - 1;
}//返回key的后继下标,如果不存在返回-1;
int  GetNext(PSQList ps, int key)
{int i = Search(ps, key);if (i < 0 || i == ps->length - 1)//注意,尾没有后继{return -1;}return i + 1;
}//输出
void  Show(PSQList ps)
{assert(ps != NULL);if (ps == NULL){return;}for (int i = 0; i < ps->length ; i++){printf("%d  ", ps->elem[i]);}printf("\n");
}//清空数据
void  Clear(PSQList ps)
{ps->length = 0;
}//销毁整个内存
void  Destroy(PSQList ps)
{Clear(ps);
}

test.cpp //main函数

#include 
#include 
//#include "sqlist.h"int main()
{SQList sq;printf("%d\n", sizeof(sq));InitSqlist(&sq);//测试插入数据//Insert(&sq, 0, 100);for (int i = -1; i < 20; i++)//循环保证测试的全面性{Insert(&sq, i, i);}//输出Show(&sq);//查找1int i = Search(&sq, 9);if (i >= 0){printf("该值位于%d号下标\n", i);}else{printf("没有找到该值!\n");}//查找2,循环查找,推荐这种测试int index;for (int i = -1; i < 20; i++){index = Search(&sq, i);if (index >= 0){printf("该值位于%d号下标\n", i);}else{printf("没有找到该值!\n");}}//删除DelPos(&sq, 5);//删除DelVal(&sq, 1);Show(&sq);return 0;
}

顺序表的优缺点

优点

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

缺点

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

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...