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

    数据结构——顺序表

    Content
      代码及其注释
       写在最后

    代码及其注释
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <string>
    using namespace std;// 头文件说明:此代码为C++代码,使用的是C++头文件
    
    /**********线性表---顺序表**********/
    // 说明:本代码主观性比较强,仅供参考,欢迎交流和学习
    // 宏定义常量
    #define LIST_INIT_SIZE 100 // 初始分配空间
    #define LISTINCREMENT 10   // 空间分配增值
    #define TRUE 1
    #define FALSE 0
    #define OK 1
    #define ERROR 0
    #define INFEASBLE -1
    #define OVERFLOW -2
    
    typedef int ElemType;
    typedef int Status;
    
    typedef struct
    {
        ElemType *elem; // 头指针
        int length;     // 顺序表使用长度
        int listsize;   // 顺序表总长
    } SqList;
    
    // 基本操作:
    Status InitList_Sq(SqList *L);                      // 构造空的顺序表(算法2.2)
    void DestoryList(SqList *L);                        // 销毁顺序表
    void QuitList(SqList *L);                           // 清空顺序表
    Status ListLength(SqList *L);                       // 返回顺序表长度
    Status ListInsert_Sq(SqList &L, int i, ElemType e); // 在第i个位置前插入新的元素(算法2.3)
    Status ListDelet_Sq(SqList &L, int i, ElemType &e); // 删除位置i处的元素并用e返回被删除元素(算法2.4)
    void ListPrint(SqList *L);                          // 打印顺序表
    int LocateElem_Sq(SqList *L, ElemType e, Status (*compare)(ElemType, ElemType));
    /**/                                               // 找查顺序表中元素位置(算法2.5)
    void MergList(SqList *La, SqList *Lb, SqList *Lc); // 合并降序顺序表为新的大顺序表(算法2.6)
    void GetElem(SqList *L, int i, ElemType &e);       // 取出顺序表中为序为 i 的元素
    Status compare(ElemType elem1, ElemType elem2);
    void ListDescendingSort(SqList *L); // 顺序表降序排序
    
    int main()
    {
        SqList L; // 定义表头
        ElemType e;
        // 函数功能展示:
        // 1 创建初始化顺序表
        InitList_Sq(&L);
    
        // 2 插入元素
        for (int i = 10; i > 0; i--)
            ListInsert_Sq(L, 1, i);
    
        // 3 输出顺序表
        printf("PRINT_LIST-> L: ");
        ListPrint(&L);
    
        // 3 删除顺序表某个位序上的元素
        ListDelet_Sq(L, 10, e);
        printf("已删除:%d
    ", e);
        printf("PRINT_LIST-> L: ");
        ListPrint(&L);
    
        // 4 找查元素位序
        printf("元素5在位序-%d-
    ", LocateElem_Sq(&L, 5, compare));
    
        // 降序排序 L 与 LL
        SqList LL;
        InitList_Sq(&LL);
        for (int i = 5; i > 0; i--)
            ListInsert_Sq(LL, 1, i);
        ListDescendingSort(&L);// 使L降序
        printf("PRINT_LIST-> L:");
        ListPrint(&L);
        ListDescendingSort(&LL);// 使LL降序
        printf("PRINT_LIST-> LL:");
        ListPrint(&LL);
    
        // 合并顺序表 L 与 LL 到 LLL
        SqList LLL;
        InitList_Sq(&LLL);
        MergList(&L, &LL, &LLL);// 合并L与LL到LLL
        printf("PRINT_LIST-> LLL:");
        ListPrint(&LLL);
        return 0;
    }
    
    // 构造线性表
    Status InitList_Sq(SqList *L)
    {
        L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
        /* 
        malloc申请内存    使用格式:(类型*)malloc(空间大小)
        elem 指向所申请内存空间的首地址
        malloc函数申请空间失败返回值是NULL,若失败L->elem == NULL  */
        if (!L->elem) // 等效于 L->elem == NULL
            exit(OVERFLOW);
        L->length = 0; // 此函数仅仅是创造一片空间,为储存数据时为空表
        L->listsize = LIST_INIT_SIZE;
        return OK;
    } // 函数作用:开辟一连串"物理空间连续"的内存用于数据存储,创建顺序表完后任务结束
    
    // 销毁线性表
    void DestoryList(SqList *L)
    {
        free(L);
        return;
    }
    // 清空顺序表
    void QuitList(SqList *L)
    {
        L->length = 0;
        return;
    }
    
    Status ListLength(SqList *L)
    {
        return L->length; // 返回顺序表长度
    }
    
    Status compare(ElemType c1, ElemType c2)
    {
        if (c1 == c2) // 比较两个元素是否相同
            return TRUE;
        else
            return FALSE;
    }
    
    // 在第i个位置前插入新的元素
    Status ListInsert_Sq(SqList &L, int i, ElemType e)
    {
        if (i < 1 || i > L.listsize)
            return ERROR; // 插入位置只能是开始-->末尾(1 <= i <= listsize)
        if (L.length >= L.listsize)
        {
            ElemType *newbase =
                (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
            // 由于空间不够将申请新的空间使用,用newbase记录新的空间的首地址
            if (!newbase)
                exit(OVERFLOW);
            L.elem = newbase; // 让链表头指针指向重新分配的内存
            free(newbase);
            L.listsize += LISTINCREMENT;
        }
        ElemType *InsertPozition = &(L.elem[i - 1]); // 记录插入位置的地址
        for (ElemType *p = &(L.elem[L.length]); p >= InsertPozition; --p)
            *(p + 1) = *p; // 将a[j]位置的元素拷贝到a[j+1](i <= j <= length+1)
        L.length++;
        *InsertPozition = e; // 插入新的元素
        return OK;
    } // 函数作用:将插入位置i后的所有元素往尾挪动一位,空出位置i以存储新的元素
    
    // 删除位置i处的元素并用e返回被删除元素
    Status ListDelet_Sq(SqList &L, int i, ElemType &e)
    {
        if (i < 1 || i > L.length)
            return ERROR;               // 保证将删除数据合法
        ElemType *p = &(L.elem[i - 1]); // 记录被删除数据的位置
        e = L.elem[i - 1];
        for (ElemType *end = &(L.elem[L.length - 1]); p <= end; ++p)
            *p = *(p + 1); // end记录结尾位置,p只移动到end
        L.length--;
        return OK;
    } // 函数作用:将i --> 最后的元素全部往头挪动一位;用e返回删除的i处的元素
    
    void ListPrint(SqList *L)
    {
        for (int i = 0; i < L->length; i++)
            // printf("List[%d] = %d
    ", i, L->elem[i - 1]);
            printf("%d ", L->elem[i]); // 逐个输出表中的元素
        putchar('
    ');
    }
    
    /*函数说明:
    1. 两个降序序顺序表合并为一个顺序表
    2. La Lb 一定是提前按照降序排序好了的否则运行结果很惊喜
    3. 实现思路:通过不断比较La、Lb中的数值,取较大的写入Lc
    */
    void MergList(SqList *La, SqList *Lb, SqList *Lc)
    {
        ElemType *pa = La->elem, *pb = Lb->elem; // 获取la、lb的首地址
        Lc->listsize = La->length + Lb->length;  // 确定顺序表Lc的大小
        ElemType *pc = (ElemType *)malloc(Lc->listsize * sizeof(ElemType));
        Lc->elem = pc; // 申请新的空间并让Lc->elem指向新的空间的首地址
        if (!Lc->elem)
            return exit(OVERFLOW); // 内存分配失败
        ElemType *La_last, *Lb_last;
        La_last = La->elem + La->length,
        Lb_last = Lb->elem + Lb->length; // 记录顺序表的末位置
        while (pa < La_last && pb < La_last)
            if (*pa > *pb)
                *pc++ = *pa;
            else
                *pc++ = *pb; // 选择较大的元素存入Lc
        while (pa < La_last)
            *pc++ = *pa++;   // La中剩余元素拷贝至Lc
        while (pb < Lb_last)
            *pc++ = *pb++;   // Lb中剩余元素拷贝至Lc
        Lc->length = La->length + Lb->length; // 更新顺序表的长度
        return;
    }
    
    // 查找顺序表中的第一个元素e,找到则返回它的位序,否则返回0
    int LocateElem_Sq(SqList *L, ElemType e, Status (*compare)(ElemType, ElemType))
    {
        ElemType *p = L->elem;
        int index = 1;
        while (index <= L->length && !compare(*p++, e))
            index++;
        // 循环条件为i在顺序表范围内,并且未找到该元素(未找到指定元素compare的返回值是0)
        // 如果到最后一个元素了,还未找到只当元素,就会使i++,这样的话 i 就比L->length大 1
        if (index <= L->length)
            return index; // 如果i在顺序表的长度范围内说明找到了该元素
        else
            return 0;
    }
    
    // 取出顺序表中为序为 i 的元素
    void GetElem(SqList *L, int i, ElemType &e)
    {
        ElemType *p = L->elem;
        int j = 1;
        while (j++ < i && p++)
            ; // 循环使得指针指向为序为 i 的位置
        e = *p;
    }
    
    // 顺序表降序排序
    // 特别说明,ELemType为int型可以使用此方法,换做为别的类型,此思路仅供参考
    void ListDescendingSort(SqList *L)
    {
        ElemType *p = L->elem, *q;
        for (int i = 0; i <= L->length; i++, p++)
        {
            q = p + 1;
            for (int j = i; j <= L->length; j++, q++)
                if (*p < *q)
                {
                    ElemType temp = *p;
                    *p = *q;
                    *q = temp;
                }
        } // 冒泡排序
        return;
    }
    
    
    写在最后
    本代码主观性比较强,仅供参考,欢迎交流和学习。代码若有不足之处还希望大佬们指出反馈,Kirk再这里先谢谢了。每一个能读到这里的reader,你将来一定会很不错,一起加油吧!
  • 相关阅读:
    云时代架构读后感
    余额宝技术架构读后感
    shiyan
    11111
    编写hdfs文件遇到的问题
    123
    啦啦啦
    Hadoop安装
    js根据银行卡号进行判断属于哪个银行并返回银行卡类型
    git 使用
  • 原文地址:https://www.cnblogs.com/kirk-notes/p/14508023.html
Copyright © 2011-2022 走看看