zoukankan      html  css  js  c++  java
  • 老郭带你学数据结构(C语言系列)2-线性表之动态顺序表

    一、基本概念:

    线性表:由n个类型相同的数据元素组成的有限序列,记为(a1,a2,……an)。

    线性表的特征:其中的元素存在这序偶关系,元素之间存在着严格的次序关系。

    顺序存储表:线性表中的元素依次存放在一组地址连续的存储单元(数组)中。

    存储特点:若已知首元素的起始地址a0和每个元素占用的空间m,则计算第i个元素的存储位置:ai = a0 + (i - 1)m。

    顺序表的特征:(1)在逻辑上相邻的元素,在物理上也是相邻
    (2)知道表中起始元素的地址,线性表中的任一个元素地址都可以确定,因此很容易实现对线性表中的元素的随机访问。

    动态顺序表:动态存储分配方式实现

    二、代码实现:

    1)结构实现(行号是为了阅读和说明代码方便,请复制代码是忽略行号)

    typedef int ElemType;           //定义一种数据类型
    #define INITSIZE 60             //定义一个动态表的初始化大小的值
    
    typedef struct{                 //封装了数据类型
        ElemType *data;
        int len;
        int listSiz;
    } SqList;
    

    2)抽象数据类型(主要是为了说明定义的结构(本例中是顺序表)支持的运算操作,为了使用上的方便,建议使用头文件加实现的方式来运用,引入了bool变量,包含头文件stdbool.h)

    void listInit(SqList *L);                       //表的初始化
    bool listEmpty(SqList L);                       //判断表是否为空  
    bool listFull(SqList L);                        //判断表是否已满   
    void listCreate(SqList *L);                     //创建表 
    void listPrint(SqList L);                       //输出表的内容
    void listDestroy(SqList *L);                    //表的销毁,涉及内存分配,因此必须free   
    void listInsert(SqList *L, int i, ElemType e);  //在表中i的位置插入元素e                   
    int listLength(SqList L);                       //获取表的长度
    int listSerch(SqList L, ElemType e);            //在表中查找元素e,返回其在表中的位置   
    ElemType listDelete(SqList *L, int i);          //删除表中位置为i的元素,并返回删除元素的值  
    ElemType listVisit(SqList L, int i);            //访问表中第i个元素,并返回元素的值

    3)头文件实现
    将1)和2)中的代码整合后,在第4行加上#ifndef SqList_H,在第42行加上#endif,实际项目中这样作是为了避免重复定义和引用头文件,文件名为SqList.h,完整代码如下:

    #include <stdbool.h>
    
    typedef int ElemType;
    #ifndef SqList_H
    #define SqList_H
    #define INITSIZE 60
    
    typedef struct{
        ElemType *data;
        int len;
        int listSiz;
    } SqList;
    
    void listInit(SqList *L);                       //表的初始化
    bool listEmpty(SqList L);                       //判断表是否为空  
    bool listFull(SqList L);                        //判断表是否已满   
    void listCreate(SqList *L);                     //创建表 
    void listPrint(SqList L);                       //输出表的内容
    void listDestroy(SqList *L);                    //表的销毁,涉及内存分配,因此必须free   
    void listInsert(SqList *L, int i, ElemType e);  //在表中i的位置插入元素e                   
    int listLength(SqList L);                       //获取表的长度
    int listSerch(SqList L, ElemType e);            //在表中查找元素e,返回其在表中的位置   
    ElemType listDelete(SqList *L, int i);          //删除表中位置为i的元素,并返回删除元素的值  
    ElemType listVisit(SqList L, int i);            //访问表中第i个元素,并返回元素的值
    
    #endif
    

    4)操作算法实现,实现头文件定义的顺序表的操作,文件名为SqList.c(注意头文件和和实现文件名字一模一样,只有后缀名由区别),具体代码如下:

    #include <stdio.h>                                                                                                                                                          
    #include <stdlib.h>
    #include "SqList.h"
    
    void listInit(SqList *L){
        (*L).data = (ElemType *)malloc(sizeof(ElemType) * INITSIZE);
        if(0 == (*L).data){
            return;
        }
        (*L).len = 0;
        (*L).listSize = INITSIZE;
    }
    
    bool listEmpty(SqList L){
        return (0 == L.len);
    }
    
    bool listFull(SqList L){
        return (listSize == L.len);
    }
    
    void listCreate(SqList *L){
        printf("please input the lenth of list:");
        scanf("%d", &((*L).len));
        if((*L).len > (*L).listSize){
            (*L).listSize = (*L).len + INITSIZE / 2;
            free((*L).data);
            (*L).data = (ElemType *)malloc(sizeof(ElemType) * (*L).listSize);
            if(0 == (*L).data){
                return;
            }
        }
        for(int i = 0; i <= (*L).len; i++){
            printf("please input NO%d element: ", i);
            scanf("%d", &((*L).data[i]));
        }
    
        return;
    }
    
    void listPrint(SqList L){
        for(int i = 0; i < L.len; i++){
            printf("%d	", L.data[i]);
        }
        printf("
    ");
    
        return;
    }
    
    void listDestroy(SqList *L){
        free((*L).data);
        (*L).data = NULL;
        (*L).len = 0;
        (*L).listSize = 0;
    
        return;
    }
    
    void listInsert(SqList *L, int i, ElemType e){
        if(i < 0 || i > (*L).len){
            return;
        }
        if(listFull(*L)){
            (*L).listSize = (*L).listSize + INITSIZE / 2;
            (*L).data = (ElemType *)realloc(sizeof(ElemType) * (*L).listSize);
            if(0 == (*L).data){
                return;
            }
        }
        for(int j = (*L).len - 1; j >= i - 1; j--){
            (*L).data[j + 1] = (*L).data[j];
        }
        (*L).data[i - 1] = e;
        (*L).len++;
    
        return;
    }
    
    int listLength(SqList L){
        return L.len;
    }
    
    int listSerch(SqList L, ElemType e){
        for(int i = 0; i < L.len; i++){
            if(e == L.data[i]){
                return i;
            }
        }
    
        return -1;
    }
    
    int listDelete(SqList *L, int i){
        if(i < 0 || i > (*L).len){
            return -1;
        }
        if(listEmpty(*L)){
            return -2;
        }
        ElemType e = (*L).data[i - 1];
        for(int j = i; j < (*L).len; j++){
            (*L).data[j - 1] = (*L).data[j]
        }
        (*L).len--;
    
    
  • 相关阅读:
    非常实用的原创小工具:EasyIP
    ORACLE日期时间函数大全
    Windows 下单机最大TCP连接数
    如何自动以管理员身份运行.NET程序?
    ExecuteScalar 返回值问题
    Assembly类
    .Net字符串驻留池
    进程Process
    C#连接Oracle数据库(直接引用dll使用)
    谈Linux与Windows的比较
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/6823111.html
Copyright © 2011-2022 走看看