access表怎么生成表结构_数据结构线性表之顺序表

    5f0fa2d1be8f46a6b4c395699cc388dd.png今天正式开工!开始总结数据结构这部分知识.

8eadebba615292c17d2bb42ddea79a16.png

    在正式总结前,我们梳理下数据结构的内容,算是绪论内容吧。

00

知识框架

b34f342fa04e6d89d83b0a211496cc26.png

在数据结构三要素中,我们主要梳理下 数据的逻辑结构和物理结构。

【数据逻辑结构】

2de38a87a71ac5da286a7aef351a48cd.png

    逻辑结构是指数据元素之间的逻辑关系,即从逻辑关系上描述数据。它与数据的存储无关,是独立于计算机的。常见的数据逻辑结构分类如上图1.1。    集合   结构中的数据元素之间除了“同属于一个集合”的关系外,别无其他关系。    线性结构  结构中的数据元素之间只存在一对一的关系。    树形结构  结构中的数据元素之间存在一对多的关系。    图状结构或网状结构  结构中的数据元素之间存在多对多的关系。

【数据的存储结构】

    存储结构是指数据结构在计算机中的表示(又称映像),也称物理结构。它包括数据元素的表示和关系的表示。数据的存储结构是逻辑结构用计算机语言的实现,它依赖于计算机语言。数据的存储结构主要有:顺序存储、链式存储、索引存储和散列存储。关于这些存储结构的定义请大家自行搜索理解。

【ADT】

    抽象数据类型(ADT)是指一个数学模型以及定义在该模型上的一组操作,通常用(数据对象、数据关系、基本操作集)这样的三元组来表示抽象数据类型。因此可以用ADT定义一个完整的数据结构。

17e261682b9fcc16aa7d537a115adcf3.png

线性表

    【知识框架】

6ef0de1e7836068bcfa2dab42fab1e0d.png

01

理论知识

【线性表的定义】

facc556846fa01b5ef6fab1596f41b9a.png

【线性表的基本操作】

    线性表的主要操作有:

e8c31fa73452507537b9d7788253aa34.png

【顺序表的定义】

    线性表的顺序存储又称顺序表。它是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。第一个元素存储在线性表的起始位置,第i个元素的存储位置后面紧接着存储的是第i+1元素,称i为元素0dac375205c156cbba2b9d6f14566e10.png在线性表中的位序。因此,顺序表的特点是表中元素的逻辑顺序与其物理顺序相同。

176d9c81b3d800d7bde391732117f849.png

    注意:线性表中元素的位序是从1开始的,而数组中元素的下表是从0开始

    假定线性表的元素类型为ElemType,则线性表的顺序存储类型使用C语言描述为

#define MaxSize 50  //定义线性表的最大长度typedef struct{     ElemType data[MaxSize]; //顺序表的元素    int length; //顺序表的当前长度}SqList;     //顺序表的类型定义

    一维位数组可以是静态分配的,也可以是动态分配的,在静态分配中由于数组大小和空间已定,一旦空间占满,再加入新的数据将会产生溢出,进而导致程序崩溃。

    而在动态分配中,存储数组的空间是在程序执行过程中通过动态分配语句分配的,一旦数据空间占满,就另外开辟一块更大的存储空间,用以替换原来的存储空间,从而达到扩充存储数组空间的目的,而不需要为线性表一次性的划分所有空间。

#define InitSize 100 //表长度的初始定义typedef struct{    ElemType *data;   //指示动态分配数组的指针    int MaxSize,length;  //数组的最大容量和当前个数 } SeqList;       //动态分配数组顺序表的类型定义

    C的初始动态分配语句为

L.data = (ElemType*)malloc(sizeof(ElemType)*InitSize);

    C++的初始动态分配语句为

L.data = new ElemType[InitSize];

4748cd166663d7ba29cbd357a4e3879d.png

顺序表最主要的特点是 随机访问,即通过首地址和元素序号可在时间O(1)内找到指定的元素。顺序表的存储密度高,每个结点只存储数据元素。顺序表逻辑上相邻的元素物理上也相邻,所以插入和删除操作需要移动大量元素。

02

编程实现

    考虑到自己日后以Go语言为主要工作语言,因此我会将所有的数据结构以Go语言改写,当然C/C++如何实现也是需要掌握的,理论知识暂且以C/C++进行总结。

package mainimport "fmt"// SqList  is a sqlist file//定义顺序表type SqList struct{  //定义顺序表的最大长度  maxSize int  //定义当前顺序表的长度  length int  //顺序表的元素  data []int}//InitSqList is to initmylist//初始化顺序表func InitSqList(InitSize int) *SqList{  return &SqList{maxSize: InitSize, data: make([]int, InitSize)}}//IsEmpty is or not empty//检查顺表是否为空//方法是查看当前顺序表的长度是否为0 func (mySqList *SqList) IsEmpty() bool{  return mySqList.length == 0}//IsFull is or not full//判断当前顺序表长度是否已达到最大值func (mySqList *SqList) IsFull() bool{  return mySqList.length == mySqList.maxSize}//ListInsert function is to insert an element//在i位置插入元素efunc (mySqList *SqList) ListInsert(i, e int) bool{  if i < 1 || i > mySqList.length + 1 {    fmt.Println("不合法,请检查i")    return false  }  if i > mySqList.maxSize {    fmt.Println("不合法,请检查i")    return false  }  for j := mySqList.length; j >= i; j--{  //将第i个元素及之后的元素后移    mySqList.data[j] = mySqList.data[j-1]  }  mySqList.data[i-1] = e    //在位置i处放入e  mySqList.length++        //线性表长度加1  return true}//ListAppend function is to append an element//在尾部追加一个元素,需要和最大长度比较func (mySqList *SqList) ListAppend(e int) bool{  if mySqList.IsFull() {    fmt.Println("sorry list is maxsize")    return false  }  mySqList.data[mySqList.length] = e  mySqList.length++  return true}//ListDelete function is to remove en element//此方法是用来删除指定位置元素 //method 1func (mySqList *SqList) ListDelete(i int) bool{  if i < 1 || i > mySqList.length + 1 {    fmt.Println("i不合法,请检查i")    return false  }  if i > mySqList.maxSize {    fmt.Println("i不合法,请检查i")  }  for j := i-1; j -1; j++{      mySqList.data[j] = mySqList.data[j+1]  }  mySqList.data[mySqList.length-1] = 0  mySqList.length--  return true      }//ListDelete function is to remove element//method2// func (mySqList *SqList) ListDelete(i int) bool{//   if i < 1 || i > mySqList.length + 1 {//     fmt.Println("i不合法,请检查i")//     return false//   }//   if i > mySqList.maxSize {//     fmt.Println("i不合法,请检查i")//   }//区别主要在这里,有两种思路//   for( j := i; j < mySqList.length; j++){//     mySqList.data[j-1] = mySqList.data[j]//   }//   mySqList.length--//   return true// }//ListFind function is to find an element//此方法用来查找指定位置的元素func (mySqList *SqList) ListFind(i int) bool{  if i < 1 || i > mySqList.length + 1 {    fmt.Println("i不合法,请检查i")    return false  }  if i > mySqList.maxSize {    fmt.Println("i不合法,请检查i")    return false  }  fmt.Println(mySqList.data[i-1])  return true}func main(){    list := InitSqList(20)  //设置最大长度为20  list.ListInsert(1,22)  list.ListAppend(12)  list.ListAppend(122)  list.ListAppend(133)  list.ListAppend(143)  list.ListAppend(153)  list.ListAppend(173)  list.ListAppend(183)  list.ListAppend(193)  list.ListAppend(163)  fmt.Println(&list)  fmt.Println(*list)  fmt.Println(*&list.length)  list.ListDelete(5)  //fmt.Println(*&list.data[2])  fmt.Println(*list)  list.ListFind(3)}

    程序执行结果是

4161bdbffe27a1240a080d7fdf41ebf1.png

b98cd28c-c154-eb11-8da9-e4434bdf6706.svg aac82f32706fd51aae0c97ec2c592e86.png

注意:区别顺序表的位序和数组下标。理解为什么判断插入位置是否合法时if语句中用length+1,而移动元素的for语句中只用length?

bf8cd28c-c154-eb11-8da9-e4434bdf6706.svg

03

算法复杂度分析

【插入操作】

最好情况:在表尾插入(即i=n+1)元素后移语句将不执行,时间复杂度为O(1).

最坏情况:在表头插入(即i=1),元素后移语句将执行n次,时间复杂度为O(n).

平均情况:假设6ab48a779a09b040fa93206ecd8695c7.png是在第i个位置上插入一个结点的概率,则在长度为n的线性表中插入一个结点时所需移动结点的平均次数为

478ab26f7755a49bab5ac59329d6a0bb.png

因此,线性表插入算法的平均时间复杂度为O(n).

【删除操作】

最好情况:删除表尾元素(即i=n)无需移动元素,时间复杂度为O(1).

最坏情况:删除表头元素(即i=1)需要移动除第一个元素外的所有元素,时间复杂度为O(n).

平均情况:假设210f1b97f24e29df1e7732d2bae2e869.png是删除第i个位置上结点的概率,则在长度为n的线性表中删除一个结点时所需移动结点的平均次数为

12539338aa968915bc06a5fbe456e177.png

因此,线性表删除算法的平均时间复杂度为O(n).

【按值查找】顺序查找

最好情况:查找的元素就在表头,仅需比较一次,时间复杂度为O(1).

最坏情况:查找的元素在表尾(或不存在)时候,需要比较n次,时间复杂度为O(n).

平均情况:假设75eaec4cf82f98f9427bd5c964110f01.png是查找的元素在第i(1<=i<=L.length)个位置上的概率,则在长度为n的线性表中查找值为e的元素所需比较的平均次数为

949e17fa5dff0913461ab0011c65448a.png

因此,线性表按值查找算法的平均时间复杂度为O(n).

fa2e5019f93ee8441c7fbc3022a666e8.png

end

f0dc4ec7560349750efbe41b9826d4ce.png

说明:考虑到时间成本,有些理论知识截图借鉴了部分计算机专业教材。还有考虑到一些数学符号问题,会逐渐使用LaTex命令进行排版。另外,由于每个部分知识点较多,故可能不会日更8e713439898d4b59e067dbd93164630d.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值