zoukankan      html  css  js  c++  java
  • 1.顺序表

    1.1 顺序表基本概念

    顺序表十分简单,简明扼要两句话

    • 逻辑上:线性结构
    • 物理上:地址连续的存储单元

    1.2 顺序表构造

    顺序表用结构体来定义

    typedef struct 
    {
        ElemType *data;
        int length;
    }SqList;
    

    顺序表的基本功能如下:

    • 初始化
    • 定位数据
    • 获取长度
    • 获取数据
    • 插入数据
    • 删除数据
    • 判空
    • 销毁

    写成接口,至于参数为啥这么给的,得看后面的具体实现了。

    /* base functions */
    // init function
    bool InitList(SqList *L);
    
    //get length
    int Length(SqList L);
    
    //locate data
    int LocateElem(SqList L, ElemType e);
    
    //get data
    ElemType GetElem(SqList L, int i);
    
    // insert data
    bool ListInsert(SqList *L, int i, ElemType e);
    
    
    // delete data
    bool ListDelete(SqList *L, int i, ElemType *e);
    
    //print data
    bool PrintList(SqList L);
    
    //wheater list is empty
    bool Empty(SqList L);
    
    // clear all the data
    bool DestroyList(SqList *L);
    
    

    1.3 顺序表实现

    开始之前, 先为了程序看起来更加人性化,定义一些便于理解的宏变量。

    #define ElemType int
    #define MaxSize 50
    #define InitSize 100
    #define bool short
    #define true 1
    #define false 0
    

    1.3.1 初始化

    使用动态申请内存的方式初始化顺序表,若初始化失败则退出。
    初始化顺序表长度为0。

    bool InitList(SqList *L){
        L->data = (ElemType*)malloc(InitSize * sizeof(ElemType));
        if(!L->data)
            exit(-1);
        L->length = 0;
    
        return true;
    }
    

    1.3.2 定位数据

    根据数据按顺序往下找就完事了,找到了返回位置,找不到就返回0, 注意第一个位置是1。

    int LocateElem(SqList L, ElemType e){
        int i;
        for(int i=0; i < L.length; ++i){
            if(L.data[i] == e)
                return i+1;
        }
        return 0;
    }
    

    1.3.3 获取长度

    int Length(SqList L){
        return L.length;
    }
    

    1.3.4 获取数据

    根据位置返回数据。

    ElemType GetElem(SqList L, int i){
        return L.data[i];
    }
    

    1.3.5 插入数据

    根据位置插入数据。
    如果位置超过返回,直接返回失败;
    从当前顺序表中的最后一个数据的后面(注意顺序表的长度length指向最后一个数据的后面)开始,依次将数据往后挪,直到需要插入的位置为止。
    插入后将长度加1。

    bool ListInsert(SqList *L, int i, ElemType e){
        if(i < 1 || i > L->length+1) 
            return false;
    
        if(L->length >= MaxSize)
            return false;
    
        for(int j=L->length; j >= i; j--)
            L->data[j] = L->data[j-1];
        L->data[i-1]=e;
        L->length++;
        return true;
    }
    

    1.3.6 删除数据

    首先进行合理性检测,检查位置是否在范围内。
    将要删除的数据赋值返回。
    从删除的位置开始依次将数据往前挪,最后将长度减1。

    bool ListDelete(SqList *L, int i, ElemType *e){
        if(i < 1 || i > L->length)
            return false;
    
        *e = L->data[i-1];
        for(int j=i; j < L->length; ++j)
            L->data[j-1] = L->data[j];
        L->length--;
        return true;
    }
    

    1.3.7 判空

    这里使用了三目运算符。

    bool Empty(SqList L){
        return L.length == 0?true:false;
    }
    

    1.3.8 销毁

    释放指针所指的内存即可,注意将指针指空,并把长度设为0。

    bool DestroyList(SqList *L){
        free((L->data));
    
        L->data = NULL;
        L->length = 0;
        return true;
    }
    

    1.3.9 测试

    为了测试方便再加个打印函数。

    bool PrintList(SqList L){
        for(int i = 0; i < L.length; ++i)
            printf("%d ", L.data[i]);
        printf("
    ");
        return true;
    }
    

    完整测试代码如下,对顺序表进行上述功能测试。

    int main(){
        SqList L;
        ElemType e = 4;
    
        printf("Initialize List...
    ");
        InitList(&L);
        
        printf("Insert data...
    ");
        for(int i = 1; i <= 6; ++i)
            ListInsert(&L, i, 2*i);
    
        printf("List==>");
        PrintList(L);
    
        printf("Get length...
    ");
        int len = Length(L);
        printf("Length==>%d
    ", len);
    
        printf("locate data...
    ");
        int loc = LocateElem(L, e);
        printf("locate at {%d}
    ", loc);
    
        printf("Get data...
    ");
        int elem = GetElem(L, 1);
        printf("Get data==>%d
    ", elem);
    
        printf("delete data...
    ");
        int del;
        ListDelete(&L, loc, &del);
        printf("Delete Data==>%d
    ", del);
        printf("List==>");
        PrintList(L);
    
        DestroyList(&L);
        bool isEmpty = Empty(L);
        if(isEmpty) printf("Empty!
    ");
    
        return 0;
    }
    

    1.4 顺序表应用

    1. 从顺序表删除最小元素(假设唯一)并返回该值,空出的位置由最后一个元素填补。
      过于简单不做分析。
    bool Del_Min(SqList *L, ElemType *value){
        if(!L->length)
            return false;
    
        int min = 0;
        for(int i = 1; i < L->length; ++i){
            if(L->data[min] > L->data[i])
                min = i;
        }
        *value = L->data[min];
        L->data[min] = L->data[--L->length];
        return true;
    }
    

    2.将顺序表逆置,空间复杂度要求O(1)。
    分别从头尾开始,交换每个数据。

    bool ReverseList(SqList *L){
        if(!L->length)
            return false;
    
        for(int i=0, j=L->length-1; i < j; ++i,--j){
            swap(&L->data[i], &L->data[j]);
        }
        return true;
    }
    

    3.对长度为n的顺序表L, 删除L中所有值为x的数据元素。
    方法一:将顺序表中不等于x的值按顺序保存,用k记录不等于k的个数,最后修改长度为k。

    bool Del_x_1(SqList *L, ElemType x){
        int k = 0;
        for(int i = 0; i < L->length; ++i){
            if(L->data[i] != x)
                L->data[k++] = L->data[i];
        }
        L->length = k;
        return true;
    }
    

    方法二:用k记录顺序表中等于k的值,并把不等于k的值向前移动k个位置,最后修改长度为length-k。

    bool Del_x_2(SqList *L, ElemType x){
        int k = 0;
        for(int i = 0; i < L->length; ++i){
            if(L->data[i] == x)
                k++;
            else
                L->data[i-k] = L->data[i];
        }
        L->length -= k;
        return true;
    }
    

    4.删除有序顺序表中s与t之间(s<t)的所有元。
    这个题和第3题有异曲同工之妙,按下不表。

    /*
    同第三题方法一,将L中小于等于s,大于等于t的值按顺序保存, 用k记录不等于x的个数,最后长度修改为k。
    */
    bool Del_s_t_1(SqList *L, ElemType s, ElemType t){
        if(s >= t || L->length == 0)
            return false;
    
        int k = 0;
        for(int i = 0; i < L->length; ++i){
            if(L->data[i] <= s || L->data[i] >= t)
                L->data[k++] = L->data[i];
        }
        L->length = k;
        return true;
    }
    
    
    /*
    由于是有序表,只需要找到大于等于s的第一个元素与大于等于t的第一个元素,将删除这段,只需将后面的元素前移。
    */
    bool Del_s_t_2(SqList *L, ElemType s, ElemType t){
        if(s >= t || L->length == 0)
            return false;
    
        int i, j;
        for(i = 0; i < L->length && L->data[i] < s; ++i);
        if(i == L->length) return false;
    
        for(j = i; i < L->length && L->data[j] < t; ++j);
        if(j == L->length) return false;
    
        for(; j < L->length; ++i, ++j)
            L->data[i] = L->data[j];
        L->length = i;
        return true;
     }
    

    6.从有序表中删除重复的元素。
    注意是有序表,数据只会连续重复出现。
    设置一个flag,用来标记当前数据,把接下的数据

  • 相关阅读:
    线性代数学习之初等矩阵和矩阵的可逆性
    线性代数学习之线性系统
    容器远程访问vnc--CentOS 6.8安装和配置VNC
    docker安装-单机/多机安装
    docker aufs存储驱动文件系统
    基于PowerCli自动部署和配置vmvare虚拟机
    使用Kubespray在ubuntu上自动部署K8s1.9.0集群
    python应用-pycharm新建模板默认添加shebang编码作者时间等信息
    python开发基础作业01:模拟登陆系统
    git 添加码云远程仓库和上传到码云的命令
  • 原文地址:https://www.cnblogs.com/hichens/p/14982369.html
Copyright © 2011-2022 走看看