zoukankan      html  css  js  c++  java
  • 顺序表及其多种实现方式 --- C/C++

    所谓顺序表,即线性表的顺序存储结构。下面给出的是数据结构---线性表的定义。

    ADT List{

      数据对象:

        线性表的数据对象的集合为{a1,a2,a3,...,an},每个元素的类型为ElemType。

      数据关系:

        除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每个元素有且仅有一个直接后继元素。

        数据元素之间的关系是一对一的关系。

      基础操作:

        InitList(&L);  //构造一个空的线性表

        DestroyList(&L); //销毁线性表

        ClearList(&L); //清空线性表

        ListEmpty(L); //若线性表为空,返回true,否则返回false

        ListLength(L);//求表长

        GetElem(L, i, &e); //将线性表中第i个元素赋值给e

        LocateElem(L, e, cmp()); //返回L中第一个满足cmp()函数的元素的序号,若不存在,则返回0

        ListInsert(&L, i, e); //在L中的第i个位置之前插入元素e且L的长度+1

        ListDelete(&L, i, &e); //删除L中的第i个元素并用e返回其值,且L的长度-1

        ListTraverse(L, visit()); //线性表的遍历,依次对每个元素调用visit函数

      其他操作:

        PrioElem(L, cur_e, &pre_e); //cue_e是L中的数据元素,用pre_e返回其前驱;若无前驱则操作失败

        NextElem(L, cue_e, &next_e); //cur_e是L中的数据元素,用next_e返回后继;若无后继则操作失败

        union(&L1, &L2); //求二者元素并集;又可根据线性表是否有序有不同的操作。

    }

    以下是线性表的顺序存储结构的多种实现方式,详细参阅代码。(大部分只实现了基础操作)

    1.用C语言实现顺序表 静态数组方式

    /************************************************************************
        用C语言实现顺序表 静态数组方式
    ************************************************************************/
    #include <cstdio>
    
    typedef int ElemType;
    typedef int Status;
    
    const int ERROR = 0;
    const int OK = 1;
    const int TRUE = 1;
    const int FALSE = 0;
    const int LIST_SIZE = 100;
    
    //定义顺序表结构ADT
    typedef struct{
        int elem[LIST_SIZE];
        int length;
    }SqList, *pList;
    
    //初始化顺序表
    Status InitList(pList List)
    {
        List->length = 0;
        return OK;
    }
    
    //释放顺序表
    Status DestroyList(pList List)
    {
        List->length = 0;
        return OK;
    }
    
    //判断顺序表是否为空 是 返回 1 否则 返回 0
    Status ListEmpty(pList List)
    {
        if (List->length)
            return FALSE;
        return TRUE;
    }
    
    //返回顺序表的长度
    int ListLength(pList List)
    {
        return List->length;
    }
    
    //根据下标获取元素
    Status GetElem(pList List, int i, ElemType *e)
    {
        if (i < 1 || i > List->length)
            return ERROR;
        //第i个数据元素存储在下标为i-1的数组中
        *e = List->elem[i - 1];
        return OK;
    }
    
    //判断给定数据是否为顺序表的元素
    Status LocateElem(pList List, int e)
    {
        if (ListEmpty(List))
            return ERROR;
        for (int i = 0; i < List->length; ++i)
        {
            if (e == List->elem[i])
                return TRUE;
        }
        return FALSE;
    }
    
    //返回元素的前驱
    Status PriorElem(pList List, ElemType cur_e, ElemType *pre_e)
    {
        if (0 == List->length)
            return ERROR;
        for (int i = 0; i < List->length; ++i)
        {
            if (cur_e == List->elem[i] && i != 0){
                *pre_e = List->elem[i - 1];
                return OK;
            }
        }
        return ERROR;
    
    }
    
    //返回元素cur_e的后驱
    Status NextElem(pList List, ElemType cur_e, ElemType *next_e)
    {
        if (0 == List->length)
            return ERROR;
        for (int i = 0; i < List->length - 1; ++i)
        {
            if (cur_e == List->elem[i]){
                *next_e = List->elem[i + 1];
                return OK;
            }
        }
        return ERROR;
    }
    
    //在数据元素i之前插入新元素
    Status ListInsert(pList List, int i, ElemType e)
    {
        if (i < 1 || i > List->length + 1)
            return ERROR;
        if (LIST_SIZE <= List->length)
            return ERROR;
        //q为插入位置,次位置及之后的要先移位才能在q这插入
        ElemType* q = &List->elem[i - 1];
        //移位
        for (ElemType *p = &List->elem[List->length - 1]; p >= q; --p)
            *(p + 1) = *p;
        *q = e;
        ++List->length;
        return OK;
    }
    
    //删除顺序表中的第i个数据元素,并用e返回
    Status ListDelete(pList List, int i, ElemType *e)
    {
        if (i < 1 || i > List->length)
            return ERROR;
        //p为需要删除的元素地址 讲后面的一层层移位就好 q为最后一位元素地址
        ElemType *p = &List->elem[i - 1];
        ElemType *q = &List->elem[List->length - 1];
        *e = *p;
        //移位
        while (p < q){
            *p = *(p + 1);
            ++p;
        }
        --List->length;
        return OK;
    }
    
    //线性表的遍历
    Status ListTraverse(pList List, void(*visit)(ElemType elem))
    {
        if (ListEmpty(List))
            return ERROR;
        for (int i = 0; i < List->length; ++i)
            visit(List->elem[i]);
        return OK;
    }
    
    void visit(ElemType e){
        printf("%4d", e);
    }
    
    int main()
    {
    #ifdef _LOCAL
        freopen("input.txt", "r", stdin);
    #endif
        SqList MyList;
        pList List = &MyList;
    
        InitList(List);
        ElemType tmp;
        for (int i = 1; i <= 5; ++i)
        {
            scanf("%d", &tmp);
            if (!ListInsert(List, i, tmp)){
                printf("ListInsert Error!
    ");
            }
        }
    
        //if (!ListDelete(List, 5, &tmp)){
        //    printf("ListDelete Error!
    ");
        //}
        //else{
        //    printf("Delete %d
    ", tmp);
        //}
    
        ListTraverse(List, visit); printf("
    ");
    
        return 0;
    }
    View Code


    2.C语言实现顺序表,内存动态分配方式

    /************************************************************************
        C语言实现顺序表,内存动态分配方式
    ************************************************************************/
    #include <stdio.h>
    #include <stdlib.h>
    
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    #define LIST_INIT_SIZE 15
    #define ADD_SIZE 10
    #define OVERFLOW -2
    
    typedef int ElemType;
    typedef int Status;
    
    typedef struct{
        int *elem;
        int length;    //线性表当前长度
        int listsize;    //顺序表已分配空间
    }SqList, *pList;
    
    //创建一个顺序表
    Status InitList(pList List){
        List->elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
        if (!List->elem)
            exit(OVERFLOW);
        List->length = 0;
        List->listsize = LIST_INIT_SIZE;
        return OK;
    }
    
    //销毁该顺序表
    Status DestroyList(pList List){
        if (List->elem){
            free(List->elem);
            List->elem = NULL;
            return OK;
        }
        else{
            return ERROR;
        }    
    }
    
    //判断顺序表是否为空
    Status ListEmpty(pList List){
        if (List){
            return !List->length;
        }
        return ERROR;
    }
    
    //清空顺序表
    Status ClearList(pList List){
        if (List){
            List->length = 0;
            return OK;
        }
        else{
            return ERROR;
        }
    }
    
    //返回顺序表元素个数
    Status ListLength(pList List){
        if (List){
            return List->length;
        }
        else{
            return ERROR;
        }
    }
    
    //获取元素i
    Status GetElem(pList List, int i, ElemType *e){
        if (List){
            if (i < 1 || i > List->length)
                return ERROR;
            *e = List->elem[i - 1];
            return OK;
        }
        else{
            return ERROR;
        }
    }
    
    //返回元素e的下标
    Status LocateElem(pList List, ElemType e){
        if (List){
            for (int i = 0; i < List->length; ++i)
            {
                if (e == List->elem[i])
                    return i + 1;
            }
            return 0;
        }
        else{
            return ERROR;
        }
    }
    
    //i之前插入元素
    Status ListInsert(pList List, int i, ElemType e){
        if (List){
            //插入位置出错,报错
            if (i < 1 || i > List->length + 1){
                return ERROR;
            }
            //空间已满,重新分配
            if (List->length >= List->listsize){
                //重新分配空间
                ElemType *newbase = (ElemType*)realloc(List->elem, (List->listsize + ADD_SIZE)*sizeof(ElemType));
    printf("Realloc!
    ");
                if (!newbase){
                    exit(OVERFLOW);
                }
                //将重新分配的空间赋给线性表中的指针
                List->elem = newbase;
                //更新当前已分配的空间
                List->listsize += ADD_SIZE;
            }
            //利用指针p、q移位,p指向尾元素的后一位,q指向目标地址
            ElemType *p = &List->elem[List->length];
            ElemType *q = &List->elem[i - 1];
            while (p > q){
                *p = *(p - 1);
                --p;
            }
            *q = e;
            ++List->length;
            return OK;
        }
        else
        {
            return ERROR;
        }
    }
    
    //删除i处元素
    Status ListDelete(pList List, int i, ElemType *e){
        if (List){
            if (i < 1 || i > List->length){
                return ERROR;
            }
            ElemType *p = &List->elem[i - 1];
            ElemType *q = &List->elem[List->length-1];
            while (p < q){
                *p = *(p + 1);
                ++p;
            }
            --List->length;
            return OK;
        }
        else{
            return ERROR;
        }
    }
    
    Status ListPrint(pList List)
    {
        if (List){
            for (int i = 0; i < List->length; ++i)
                printf(i ? " %d" : "%d", List->elem[i]);
            return OK;
        }
        else{
            printf("Empty List!");
            return ERROR;
        }
    }
    
    
    int main()
    {
        SqList MyList;
        pList pMyList = &MyList;
        InitList(pMyList);
        for (int i = 1; i <= 10; ++i)
            ListInsert(pMyList, i, i);
    
        ListPrint(pMyList);
    
    
        return 0;
    }
    View Code


    3.用C++实现顺序表 静态数组方式 面向对象

    /************************************************************************
        用C++实现顺序表 静态数组方式 面向对象
    ************************************************************************/
    #include <cstdio>
    
    const bool OK = 1;
    const bool ERROR = 0;
    const bool TRUE = 1;
    const bool FALSE = 0;
    const int LIST_SIZE = 100;
    
    typedef int ElemType;
    typedef int Status;
    
    class SqList{
    private:
        ElemType elem[LIST_SIZE];
        int length;
    public:
        SqList();    //默认构造函数
        ~SqList();    //析构函数
        Status ListEmpty();    //判断顺序表是否为空
        int ListLength();    //获取顺序表的长度
        Status GetElem(int i, ElemType& e);    //获取第i个元素
        Status LocateElem(int e);    //e为顺序表中的元素,返回e的下标,0表示失败
        Status ListInsert(int i, ElemType e);    //在第i个元素之前插入e并是length加1
        Status ListDelete(int i, ElemType &e);    //删除顺序表的第i个元素
        Status ListTraverse(void (*visit)(ElemType &e));    //输出该顺序表
    };
    
    void visit(ElemType& e){
        printf("%4d", e);
    }
    
    int main()
    {
        SqList Test;
        ElemType tmp;
    
        for (int i = 1; i <= 5; ++i)
            Test.ListInsert(i, i);
        //Test.ListDelete(3, tmp);
    
        Test.ListTraverse(visit);
        putchar(10);
    
    
        return 0;
    }
    
    SqList::SqList(){
        this->length = 0;
    }
    
    SqList::~SqList(){
        this->length = 0;
    }
    
    Status SqList::ListEmpty(){
        return !length;
    }
    
    int SqList::ListLength(){
        return this->length;
    }
    
    Status SqList::GetElem(int i, int& e){
        if (i < 1 || i > length)
            return ERROR;
        e = elem[i - 1];
        return OK;
    }
    
    Status SqList::LocateElem(int e){
        for (int i = 0; i < length; ++i)
        {
            if (e == this->elem[i])
                return i + 1;
        }
        return ERROR;
    }
    
    Status SqList::ListInsert(int i, int e){
        if (i < 1 || i > this->length + 1)
            return ERROR;
        if (this->length >= LIST_SIZE)
            return ERROR;
        //先将i位置及之后的元素后移,推荐使用指针实现
        ElemType *q = &this->elem[i - 1];    //q为目标地址
        for (ElemType *p = &this->elem[this->length]; p > q; --p)
        {
            *p = *(p - 1);
        }
        *q = e;
        ++length;
        return OK;
    
    }
    
    Status SqList::ListDelete(int i, int &e){
        if (i < 1 || i > length)
            return ERROR;
        //从目标地址的后一个元素开始一个个往前移
        ElemType *p = &elem[i - 1];    //p为目标地址
        ElemType *q = &elem[length];//q为尾元素的地址
        while (p < q){
            *p = *(p + 1);
            ++p;
        }
        --length;
        return OK;
    }
    
    Status SqList::ListTraverse(void(*visit)(ElemType &e)){
        if (length){
            for (int i = 0; i < length; ++i)
                visit(elem[i]);
            return OK;
        }
        else{
            printf("Empty List!");
            return OK;
        }
    
    }
    View Code

    4.用C++和模板实现顺序表

    /************************************************************************
        用C++和模板实现顺序表
    ************************************************************************/
    #include <cstdio>
    
    const int MAX_SIZE = 100;
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    //#define FALSE 0
    #define OVERFLOW -1
    typedef int Status;
    
    template<typename ElemType>
    class SqList{
        ElemType m_data[MAX_SIZE+1]; //为了排序查找方便,从1下标开始存储
        int m_length;
    public:
        //默认构造函数,相当于InitList()
        SqList() :m_length(0){}
        //析构函数,相当于DestroyList(),但什么也不做
        ~SqList(){ }
        //清空顺序表
        void ClearList(){
            m_length = 0;
        }
        //判断线性表是否为空
        bool ListEmpty(){
            return !m_length;
        }
        //求表长
        int ListLength(){
            return m_length;
        }
        //取得顺序表中的第i个元素
        Status GetElem(int i, ElemType& e){
            if (i < 1 || i > m_length)
                return ERROR;
            e = m_data[i];
            return OK;
        }
        //返回L中第一个满足cmp()函数的元素的序号,若不存在,则返回0
        Status LocateElem(ElemType e, bool(*cmp)(ElemType, ElemType)){
            m_data[0] = e;
            int i = m_length;
            while (!cmp(e, m_data[i])){
                --i;
            }
            return i;
        }
        //在L中的第i个位置之前插入元素e且L的长度+1
        Status ListInsert(int i, ElemType e){
            if (i < 1 || i > m_length + 1 || m_length >= MAX_SIZE){
                return ERROR;
            }
            for (int k = m_length; k >= i; --k){
                m_data[k+1] = m_data[k];
            }
            m_data[i] = e;
            ++m_length;
            return OK;
        }
        //删除L中的第i个元素并用e返回其值,且L的长度-1
        Status ListDelete(int i, ElemType& e){
            if (i < 1 || i > m_length)
                return ERROR;
            for (int j = i; j < m_length; ++j){
                m_data[j] = m_data[j + 1];
            }
            --m_length;
            return OK;
        }
        //线性表的遍历,依次对每个元素调用visit函数
        Status ListTraverse(void(*visit)(ElemType e)){
            if (m_length == 0){
                printf("Empty SqList");
                return ERROR;
            }
            for (int i = 1; i <= m_length; ++i){
                visit(m_data[i]);
            }
            return OK;
        }
    };
    
    bool cmp(int a, int b){
        return a == b;
    }
    
    void visit(int a){
        printf("%3d", a);
    }
    
    int main()
    {
    #ifdef _LOCAL
        freopen("input.txt", "r", stdin);
    #endif
        SqList<int> L;
        int n, tmp;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i){
            scanf("%d", &tmp);
            L.ListInsert(i, tmp);
        }
        L.ListDelete(3, tmp);
    
        L.ListTraverse(visit); printf("
    ");
    
    }
    View Code
  • 相关阅读:
    Qt编写安防视频监控系统(界面很漂亮)
    Qt编写数据可视化大屏界面电子看板系统
    Qt开源作品35-秘钥生成器
    Qt开源作品34-qwt无需插件源码
    Qt开源作品33-图片开关控件
    Qt开源作品32-文本框回车焦点下移
    Qt开源作品31-屏幕截图控件
    Qt开源作品30-农历控件
    Qt开源作品29-NTP服务器时间同步
    Qt开源作品28-邮件发送工具
  • 原文地址:https://www.cnblogs.com/tommychok/p/5084447.html
Copyright © 2011-2022 走看看