数据结构与算法笔记--线性表的使用

目录

1--线性表的基本概念 

2--线性表的顺序存储

2-1--建立空表

2-2--查找元素

2-3--插入元素

2-4--删除元素

2-5--遍历打印

2-6--测试代码

3--线性表的链式存储

2-1--计算表长

2-2--查找操作

2-3--插入操作

2-4--删除操作

2-5--测试代码


1--线性表的基本概念 

        线性表(Linear List):由同类型数据元素构成的有序序列的线性结构;

线性表中元素的个数称为线性表的长度;

线性表没有元素时,称为空表;

线性表起始位置称为表头,结束位置称为表尾;

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

类型名称:线性表(List)

数据对象集:线性表是由 n 个元素构成的有序序列(a_1, a_2, \cdots, a_n

操作集:线性表 L ∈ List,整数 i 表示位置,元素 X ∈ ElementType,其基本操作如下:

        ① List MakeEmpty(); 初始化一个空线性表L;

        ② ElementType FindKth(int K, List L); 根据位序K,返回相应元素;

        ③ int Find(ElementType X, List L); 在线性表 L 中查找 X 第一次出现的位置;

        ④ void insert(ElementType X, int i, List L); 在位序 i 前插入一个新元素 X;

        ⑤ void Delete(int i, List L); 删除指定位序 i 的元素;

        ⑥ int Length(List L); 返回线性表 L 的长度 n;

2--线性表的顺序存储

        利用数组的连续存储空间顺序存放线性表的各元素,其定义方式如下:

#define ElementType int
#define MAXSIZE 10

typedef struct LNode *List; // 别名
struct LNode{
    ElementType Data[MAXSIZE];
    int Last; // 存放最后一个元素的位置
};
// struct LNode L; // 创建线性表L
// List L; // 创建线性表L
// 线性表的长度: L->Last+1 (因为Last从0开始)
// 访问线性表的元素: L->Data[i]

2-1--建立空表

// 建立空表
List MakeEmpty(){
    List L;
    L = (List)malloc(sizeof(struct LNode));
    L->Last = -1;
    return L;
}

2-2--查找元素

// 查找元素
int Find(ElementType X, List L){
    for(int i = 0; i <= L->Last; i++){
        if(L->Data[i] == X) return i;
    }
    return -1; // 未找到
}

2-3--插入元素

// 插入元素
void Insert(ElementType X, int i, List L){ // i从0开始
    if(L->Last == MAXSIZE - 1){
        std::cout << "Error: The List is Full!" << std::endl;
        return;
    }
    if(i < 0 || i > L->Last+1){
        std::cout << "Error: Illegal insertion position!" << std::endl;
        return;
    }
    for(int j = L->Last; j>=i; j--){
        L->Data[j+1] = L->Data[j];
    }
    L->Data[i] = X;
    L->Last++;
    return;
}

2-4--删除元素

// 删除元素
void Delete(int i, List L){ // i从0开始
    if(i < 0 || i > L->Last){
        std::cout << "Error: The position is Illegal" << std::endl;
        return;
    }
    for(int j = i; j < L->Last; j++){
        L->Data[j] = L->Data[j+1];
    }
    L->Last--; // 如果删除最后一个元素,只需要将末尾指针前移即可
    return;
}

2-5--遍历打印

// 打印线性表
void PrintList(List L){
    // 遍历打印元素
    for(int i = 0; i < L->Last+1; i++){
        std::cout << L->Data[i] << " ";
    }
    std::cout<< std::endl;
}

2-6--测试代码

#include "iostream"

#define ElementType int
#define MAXSIZE 10

typedef struct LNode *List; // 别名
struct LNode{
    ElementType Data[MAXSIZE];
    int Last; // 存放最后一个元素的位置
};
// struct LNode L; // 创建线性表L
// List L; // 创建线性表L
// 线性表的长度: L->Last+1 (因为Last从0开始)
// 访问线性表的元素: L->Data[i]

// 建立空表
List MakeEmpty(){
    List L;
    L = (List)malloc(sizeof(struct LNode));
    L->Last = -1;
    return L;
}

// 查找元素
int Find(ElementType X, List L){
    for(int i = 0; i <= L->Last; i++){
        if(L->Data[i] == X) return i;
    }
    return -1; // 未找到
}

// 插入元素
void Insert(ElementType X, int i, List L){ // i从0开始
    if(L->Last == MAXSIZE - 1){
        std::cout << "Error: The List is Full!" << std::endl;
        return;
    }
    if(i < 0 || i > L->Last+1){
        std::cout << "Error: Illegal insertion position!" << std::endl;
        return;
    }
    for(int j = L->Last; j>=i; j--){
        L->Data[j+1] = L->Data[j];
    }
    L->Data[i] = X;
    L->Last++;
    return;
}

// 删除元素
void Delete(int i, List L){ // i从0开始
    if(i < 0 || i > L->Last){
        std::cout << "Error: The position is Illegal" << std::endl;
        return;
    }
    for(int j = i; j < L->Last; j++){
        L->Data[j] = L->Data[j+1];
    }
    L->Last--; // 如果删除最后一个元素,只需要将末尾指针前移即可
    return;
}

// 打印线性表
void PrintList(List L){
    // 遍历打印元素
    for(int i = 0; i < L->Last+1; i++){
        std::cout << L->Data[i] << " ";
    }
    std::cout<< std::endl;
}

int main(int argc, char* argv[]){
    List L = MakeEmpty(); // 建立空表
    // 插入元素
    Insert(1, 0, L);
    Insert(2, 1, L);
    Insert(3, 2, L);
    Insert(4, 1, L);

    PrintList(L); // 打印线性表
    std::cout<< "The length of list L: " << L->Last+1 << std::endl;

    // 查找元素
    int pos = Find(4, L);
    std::cout << "The elem " << 4 << " is in pos: " << pos << std::endl;

    // 删除元素
    Delete(1, L); // 删除idx为1的元素;
    Delete(L->Last, L); // 删除最后一个的元素;
    Delete(0, L); // 删除第一个元素

    PrintList(L); // 打印线性表
    std::cout<< "The length of list L: " << L->Last+1 << std::endl;

    return 0;
}

3--线性表的链式存储

        链式存储不强制要求逻辑相邻的两个元素必须物理相邻;可通过链建立起数据元素之间的逻辑关系;线性表链式存储的定义方式如下:

#define ElementType int
#define MAXSIZE 10

typedef struct LNode *List; // 别名
struct LNode{
    ElementType Data; // 数据域
    List Next; // 指针域
};
// struct LNode L; // 创建线性表L
// List L; // 创建线性表L

        初始化带头结点的单链表:

// 初始化带头结点的链表
bool InitList(List &L){
    L = (LNode*)malloc(sizeof(LNode)); // 头结点
    L->Next = NULL; 
    return true;
}

        遍历打印链表:

// 打印链表(带头结点)
void PrintList(const List L){
    // 从第一个数据结点开始遍历
    for(LNode *p = L->Next; p != NULL; p = p->Next){
        std::cout << p->Data << " ";
    }
    std::cout << std::endl;
}

2-1--计算表长

// 求表长(不包括头节点)
int Length(List L){
    List p = L; // 指向头结点
    int num = -1;
    while(p){
        p = p->Next;
        num++;
    }
    return num;
}

2-2--查找操作

① 按序号查找:

// 按序号查找
List FindKth(int K, const List L){
    List p = L; // 指向头结点
    int idx = 0;
    while(p != NULL && idx < K){
        p = p->Next;
        idx++;
    }
    if(idx == K) return p; // 找到第K个,返回指针
    else return NULL; // 未找到,返回空
}

② 按值查找:

// 按值查找
List FindElem(ElementType X, List L){
    List p = L; // 指向头结点
    while(p != NULL && p->Data != X){
        p = p->Next;
    }
    return p;
}

2-3--插入操作

        主要操作步骤:

① 判断插入位置是否合法;

② 找到第 i-1 个结点的位置;

③ 为新结点申请内存空间

④ 更新指针域;

// 插入操作(带头节点)
bool ListInsert(List &L, int i, ElementType e){
    if(i < 1){ // 不合法
        return false;
    }
    LNode *p = L;
    for(int j = 0; p != NULL && j < i - 1; j++){
        p = p->Next; // p指向 i-1 结点
    }
    if(p == NULL){ // 不合法
        return false;
    }
    LNode* s = (LNode*)malloc(sizeof(LNode)); // 申请新结点内存空间
    s->Data = e;
    s->Next = p->Next;
    p->Next = s;
    return true;
}

2-4--删除操作

        主要操作步骤:

① 判断删除位置是否合法;

② 找到删除结点的前一个结点,更新其指针域;

③ 释放待删除的结点;

// 删除操作
bool Delete(int i, List &L){
    if(i < 1){
        return false;
    }
    LNode *pos = FindKth(i - 1, L); // 找到第 i-1 个数据结点
    if(pos == NULL){ // 前一个数据结点不存在
        std::cout << "The Node is not exist!" << std::endl;
        return false;
    }
    else if(pos->Next == NULL){ // 前一个数据结点是最后一个结点
        std::cout << "The Node is not exist!" << std::endl;
        return false;
    }
    else{
        LNode *s = pos->Next; // 要删除的结点
        pos->Next = s->Next;
        free(s);
        return true;
    }
}

2-5--测试代码

#include "iostream"
#define ElementType int
#define MAXSIZE 10

typedef struct LNode *List; // 别名
struct LNode{
    ElementType Data;
    List Next; // 存放最后一个元素的位置
};
// struct LNode L; // 创建线性表L
// List L; // 创建线性表L

// 初始化带头结点的链表
bool InitList(List &L){
    L = (LNode*)malloc(sizeof(LNode)); // 头结点
    L->Next = NULL; 
    return true;
}

// 求表长(不包括头节点)
int Length(List L){
    List p = L; // 指向头结点
    int num = -1;
    while(p){
        p = p->Next;
        num++;
    }
    return num;
}

// 插入操作(带头节点)
bool ListInsert(List &L, int i, ElementType e){
    if(i < 1){ // 不合法
        return false;
    }
    LNode *p = L;
    for(int j = 0; p != NULL && j < i - 1; j++){
        p = p->Next; // p指向 i-1 结点
    }
    if(p == NULL){ // 不合法
        return false;
    }
    LNode* s = (LNode*)malloc(sizeof(LNode)); // 申请新结点内存空间
    s->Data = e;
    s->Next = p->Next;
    p->Next = s;
    return true;
}

// 按序号查找
List FindKth(int K, const List L){
    List p = L; // 指向头结点
    int idx = 0;
    while(p != NULL && idx < K){
        p = p->Next;
        idx++;
    }
    if(idx == K) return p; // 找到第K个,返回指针
    else return NULL; // 未找到,返回空
}

// 按值查找
List FindElem(ElementType X, List L){
    List p = L; // 指向头结点
    while(p != NULL && p->Data != X){
        p = p->Next;
    }
    return p;
}

// 删除操作
bool Delete(int i, List &L){
    if(i < 1){
        return false;
    }
    LNode *pos = FindKth(i - 1, L); // 找到第 i-1 个数据结点
    if(pos == NULL){ // 前一个数据结点不存在
        std::cout << "The Node is not exist!" << std::endl;
        return false;
    }
    else if(pos->Next == NULL){ // 前一个数据结点是最后一个结点
        std::cout << "The Node is not exist!" << std::endl;
        return false;
    }
    else{
        LNode *s = pos->Next; // 要删除的结点
        pos->Next = s->Next;
        free(s);
        return true;
    }
}

// 打印链表
void PrintList(const List L){
    for(LNode *p = L->Next; p != NULL; p = p->Next){
        std::cout << p->Data << " ";
    }
    std::cout << std::endl;
}

int main(int argc, char* argv[]){
    List L;
    InitList(L); // 初始化带头结点的链表
    ListInsert(L, 1, 10);
    ListInsert(L, 2, 20);
    ListInsert(L, 3, 30);
    ListInsert(L, 4, 40);
    // 计算表长
    int len = Length(L);
    std::cout << "The length of the list is: " << len << std::endl; 
    // 打印链表
    PrintList(L);

    LNode *p1 = FindKth(2, L); // 查找第二个数据元素
    std::cout << "Find the elem: " << p1->Data << std::endl;
    LNode *p2 = FindElem(30, L); // 查找第二个数据元素
    std::cout << "Find the elem: " << p2->Data << std::endl;

    Delete(4, L);// 删除第4个数据结点
    Delete(1, L);// 删除第1个数据结点
    PrintList(L);
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43863869/article/details/129765692