数据结构与算法(2) - 线性表及两种存储结构

1 线性表

1.1 线性表(Linear List)定义

由同类型数据元素构成的有序序列的线性结构
线性表是逻辑上的定义,不是物理存储上的定义


1.2 线性表的抽象数据类型描述

这里是抽象描述(数据对象集,有关操作)
在这里插入图片描述

1.3 线性表的存储

按照顺序结构存储的线性表称作“顺序表”,可以理解为数组。
按照链式结构存储的线性表称作“链表”


2 两种存储结构

2.1 顺序存储结构

借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系。

2.1.1 初始化

  1. 要提前申请好足够大的存储空间
  2. 要记录顺序表的长度
    例子代码
/*
 * @Brief:  循序表
 * @Author: 
 * @Date: 2021-01-29 
*/
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

typedef struct table
{
    
    
    int* head;
    int size;   // 总长度
    int length;   // 当前长度
};

// 顺序表初始化
table initTable(int ll){
    
    
    table ans;
    ans.head = (int*)malloc(ll * sizeof(int));
    if(!ans.head){
    
    
        printf("init error\n");
        exit(0);
    }
    ans.size = ll;
    ans.length = 0;
    return ans;
}

int main(){
    
    
    table LinearList = initTable(10);
    // add element to table
    for(int i = 0 ; i < LinearList.size; i++){
    
    
        LinearList.head[i] = i;
        LinearList.length++;
    }
    
    // display
    for(int i = 0 ; i < LinearList.length; i++){
    
    
        cout << LinearList.head[i] << endl;
    }

    return 0;
}

2.1.2 基本操作

插入

指定位置后边的数据元素都依次向后移动,腾出一个空位后把插入元素放进来。

删除

找到目标元素,它后边的元素依次向前移动一个位置,将其覆盖掉。

查找

可以用多种查找算法,比如二分、插值。

修改

先查找到该元素,然后直接修改。

2.2 链式存储结构

借助指示元素存储地址的指针表示数据元素之间的逻辑关系。

2.2.1 单向链表

在这里插入图片描述

插入

在第i个位置上插入新节点。
构造一个新节点B,B先指向C(插入之前的第i个节点),再用A(插入之前的第i-1个节点)指向B。

删除

删除第i个节点
先找到第i-1个节点(节点P),用临时变量S指针指向第i个节点,然后节点p指向S的下一个节点(指第i+1个节点),防止内存泄漏,要free掉S的空间。

查找

从头遍历。
分为按序号查找和按值查找。

求表长度

遍历

2.2.2 双向链表

在这里插入图片描述

2.2.3 循环链表

在这里插入图片描述

2.2.4 双向循环链表

向前、向后都形成一个环。
在这里插入图片描述

2.2.5 块状链表

广义表的基本概念

广义表是线性表的推广,其实是一个多重链表,一个线性表要么存储不可再分的数据元素(例如数字1、字符a),要么存储可再分的数据元素(例如存储数组)。但是广义表,可以同时存储这两种数据元素(不可再分元素和可再分元素)。

广义表中不可再分的元素称为原子,可再分的元素称为子表。

当广义表非空的时候,第一个元素(原子或子表)叫作表头,其余所有元素叫作表尾(表尾一定是一个广义表)。如果一个表中只有一个元素,那么他的表尾是空表。

如果一个广义表非空,那么他一定就有表头和表尾。

eg:广义表存储二元多项式

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u014117943/article/details/113357665