zoukankan      html  css  js  c++  java
  • 数据结构之线性表

    线性表

    线性表(Linear List)是n个数据元素的有限序列。
    特点:
    (1)唯一的首元素
    (2)唯一的尾元素
    (3)除首元素之外,每个元素都有唯一的前驱
    (4)除尾元素之外,每个元素都有唯一的后继

    线性表的顺序存储结构(用一组地址连续的存储单元依次存储元素):数组
    线性表的链式存储结构(用一组地址任意的存储单元去存元素):链表

    动态数组:(C实现)

    ////////////////  SqList.h 
    
    /////////////////  函数结果状态代码  /////////////
    #define TRUE 1
    #define FALSE 0
    #define OK 1
    #define ERROR 0
    #define INFEASIBLE -1
    #define OVERFLOW -2
    typedef int Status;
    /////////////////////////////////////////////////
    
    
    #define        LIST_INIT_SIZE    5        //线性表存储空间的初始分配增量
    #define        LISTINCREMENT    10        //线性表存储空间的分配增量
    
    typedef int        ElemType;//定义元素类型
    
    
    typedef struct{
        ElemType*    elem;        //存储空间基址
        int            length;        //数组的当前长度
        int            listsize;    //当前分配的存储容量(以size(ElemType)为单位)
    }SqList;
    
    //初始化
    Status InitList_Sq(SqList* pL);
    //初始化2(指定分配的长度、容量)
    Status InitList2_Sq(SqList* pL, int length, int capacity);
    
    /////////////////////////////////////////////////////////////////////////////////
    // 插入元素
    // @parameter
    //        pL    被操作的线性表list的地址
    //        i    插入元素的索引位置(base 0)
    //        e    插入的元素
    // @return
    //        Status : OK、ERROR、INFEASIBLE、OVERFLOW
    /////////////////////////////////////////////////////////////////////////////////
    Status ListInsert_Sq(SqList* pL, int i, ElemType e);
    
    /////////////////////////////////////////////////////////////////////////////////
    //    删除元素
    //    @parameter
    //        pL    被操作的线性表list的地址
    //        i    删除元素的索引 (base 0)
    //        pE    返回被删除的元素
    //    @return
    //        Status : OK、ERROR、INFEASIBLE、OVERFLOW
    /////////////////////////////////////////////////////////////////////////////////
    Status ListDelete_Sq(SqList* pL, int i, ElemType* pE);
    
    //添加元素(在尾部)
    Status AddTail_Sq(SqList* pL, ElemType elem);
    //删除尾部元素
    Status DeleteTail_Sq(SqList* pL, ElemType* pElem);
    
    /////////////////////////////////////////////////////////////////////////////////
    //    定位元素(在list中查找第一个与e满足compare()的元素的索引)
    //    @parameter
    //        L    被查找的线性表
    //        e    定位的元素
    //        compare    函数指针
    //    @return
    //        int : 成功,返回第一个与e满足compare()的元素的索引;失败,返回 -1
    /////////////////////////////////////////////////////////////////////////////////
    int LocateElem_Sq(SqList L, ElemType e, Status(*compare)(ElemType e1, ElemType e2));
    
    // 查找元素(返回list中第一个元素e的索引)
    int FindElem_Sq(SqList L, ElemType e);
    
    /////////////////////////////////////////////////////////////////////////////////
    //    合并顺序表(将两个有序的list合并为一个有序的list)
    //    @parameter
    //        La    有序list1
    //        Lb    有序list2
    //        pLc    返回合并后的list
    //    @return
    //        void
    /////////////////////////////////////////////////////////////////////////////////
    void MergeList_Sq(SqList La, SqList Lb, SqList* pLc);
    
    
    // 打印List
    void DisplyList_Sq(SqList L);
    
    //-------------------------------------------------------------------------------
    ////////////////  SqList.h 
    #include "SqList.h"
    #include <stdio.h>
    #include <stdlib.h>
    
    //初始化
    Status InitList_Sq(SqList* pL)
    {
        pL->elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
        if (NULL == pL->elem)//内存分配失败
            return OVERFLOW;
        pL->length = 0;
        pL->listsize = LIST_INIT_SIZE;
        return OK;
    }
    
    //初始化2(指定分配的长度、容量)
    Status InitList2_Sq(SqList* pL, int length, int capacity)
    {
        pL->elem = (ElemType*)malloc(capacity * sizeof(ElemType));
        if (NULL == pL->elem)//内存分配失败
            return OVERFLOW;
        pL->length = length;
        pL->listsize = capacity;
        return OK;
    }
    
    //添加元素(在尾部)
    Status AddTail_Sq(SqList* pL, ElemType elem)
    {
        return ListInsert_Sq(pL, pL->length, elem);
    }
    
    //删除尾部元素
    Status DeleteTail_Sq(SqList* pL, ElemType* pElem)
    {
        return ListDelete_Sq(pL, pL->length, pElem);
    }
    
    /////////////////////////////////////////////////////////////////////////////////
    // 插入元素
    // @parameter
    //        pL    被操作的线性表list的地址
    //        i    插入元素的索引位置(base 0)
    //        e    插入的元素
    // @return
    //        Status : OK、ERROR、INFEASIBLE、OVERFLOW
    /////////////////////////////////////////////////////////////////////////////////
    Status ListInsert_Sq(SqList* pL, int i, ElemType e)
    {//在元素L[i]之前插入元素e,i是数组下标 base 0 
        if (i < 0 || i > pL->length)
            return ERROR;
        if (pL->length >= pL->listsize)
        {
            ElemType* newbase = (ElemType*)realloc(pL->elem, (pL->listsize + LISTINCREMENT)*sizeof(ElemType));
            if (NULL == newbase)
                return ERROR;
            pL->elem = newbase;
            pL->listsize += LISTINCREMENT;
        }
        ElemType* q = &(pL->elem[i]);
        //插入位置后的元素向后移动
        for (ElemType* p = &(pL->elem[pL->length - 1]); p >= q; --q){
            *(p + 1) = *p;
        }
        *q = e;
        ++pL->length;
        return OK;
    }
    
    /////////////////////////////////////////////////////////////////////////////////
    //    删除元素
    //    @parameter
    //        pL    被操作的线性表list的地址
    //        i    删除元素的索引 (base 0)
    //        pE    返回被删除的元素
    //    @return
    //        Status : OK、ERROR、INFEASIBLE、OVERFLOW
    /////////////////////////////////////////////////////////////////////////////////
    Status ListDelete_Sq(SqList* pL, int i, ElemType* pE)
    {
        ElemType* p = NULL;
        ElemType* q = NULL;
        
        if (i < 0 || i > pL->length - 1)
            return ERROR;
    
        p = &(pL->elem[i]);//被删除元素的地址
        if (NULL != pE)
            *pE = *p;
        //被删除元素之后的元素左移
        q = pL->elem + pL->length;
        for (++p; p < q; ++p)
        {
            *(p - 1) = *p;
        }
    
        --pL->length;
        return OK;
    }
    
    /////////////////////////////////////////////////////////////////////////////////
    //    定位元素(在list中查找第一个与e满足compare()的元素的索引)
    //    @parameter
    //        L    被查找的线性表
    //        e    定位的元素
    //        compare    函数指针
    //    @return
    //        int : 成功,返回第一个与e满足compare()的元素的索引;失败,返回 -1
    /////////////////////////////////////////////////////////////////////////////////
    int LocateElem_Sq(SqList L, ElemType e, Status(*compare)(ElemType e1, ElemType e2))
    {
        //int i = 1;
        //ElemType* p = pL->elem;
        //while (i < pL->length && (TRUE != compare(*p, e)))
        //{
        //    ++i;
        //    ++p;
        //}
        //if (i < pL->length)
        //    return i;
        //return -1;
    
        int i = 0;
        for (i = 0; i < L.length; ++i)
        {
            if (TRUE == compare(L.elem[i], e))
                return i;
        }
        return -1;
    }
    
    // 比较函数
    Status compare1(ElemType e1, ElemType e2)
    {
        if (e1 == e2)
            return TRUE;
        else
            return FALSE;
    }
    // 查找元素(返回list中第一个元素e的索引)
    int FindElem_Sq(SqList L, ElemType e)
    {
        return LocateElem_Sq(L, e, compare1);
    }
    
    /////////////////////////////////////////////////////////////////////////////////
    //    合并顺序表(将两个有序的list合并为一个有序的list)
    //    @parameter
    //        La    有序list1
    //        Lb    有序list2
    //        pLc    返回合并后的list
    //    @return
    //        void
    /////////////////////////////////////////////////////////////////////////////////
    void MergeList_Sq(SqList La, SqList Lb, SqList* pLc)
    {
        ElemType* pa = La.elem;
        ElemType* pb = Lb.elem;
        ElemType* pa_last = La.elem + La.length;
        ElemType* pb_last = Lb.elem + Lb.length;
        pLc->length = pLc->listsize = La.length + Lb.length;
        ElemType* pc = pLc->elem = (ElemType*)malloc(pLc->listsize * sizeof(ElemType));
        if (NULL == pc)
            return ERROR;//分配内存失败
        //归并
        while (pa < pa_last && pb < pb_last)
        {
            if (*pa <= *pb)
                *pc++ = *pa++;
            else
                *pc++ = *pb++;
        }
        while (pa < pa_last)
            *pc++ = *pa++; //插入La的剩余元素
        while (pb < pb_last)
            *pc++ = *pb++; //插入Lb的剩余元素
    }
    
    
    void DisplyList_Sq(SqList L)
    {
        SqList* pL = &L;
        printf("list:[elem=%#x,length=%d,listsize=%d]: ", pL->elem, pL->length, pL->listsize);
        for (int i = 0; i < pL->length; ++i)
        {
            printf("	%d", *(pL->elem + i));
        }
        printf("
    ");
    }
    
    //---------------------------------------------------
    //测试
    #include <stdio.h>
    #include "SqList.h"
    int main()
    {
        //printf("hello world.
    ");
        SqList list = {  0 };
        InitList_Sq(&list);
        
        AddTail_Sq(&list, 10);
        AddTail_Sq(&list, 20);
        AddTail_Sq(&list, 30);
        AddTail_Sq(&list, 40);
        AddTail_Sq(&list, 50);
        ListInsert_Sq(&list, 5, 99);
        ElemType ele;
        ListDelete_Sq(&list, 3, NULL);
        DisplyList_Sq(list);
        //int pos = FindElem_Sq(list, 9);
        //printf("%d
    ", pos);
    
        SqList list2 = { 0 };
        //InitList2_Sq(&list2, 0, 3);
        AddTail_Sq(&list2, 11);
        AddTail_Sq(&list2, 21);
        AddTail_Sq(&list2, 60);
        DisplyList_Sq(list2);
    
        SqList list3;
        MergeList_Sq(list, list2, &list3);
        DisplyList_Sq(list3);
    }
    View Code

    常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。

    昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。
  • 相关阅读:
    MySQL表操作:字段类型 约束条件
    MySQL安装 sql语句
    O学堂作文
    iOS沙盒
    xcode 8带来的问题
    身份证号验证(省份,生日,末位校验)
    UIView的layoutSubviews和drawRect方法何时调用
    UIView超出父视图部分响应
    xcode 8带来的问题
    计算今天是周几
  • 原文地址:https://www.cnblogs.com/htj10/p/13284234.html
Copyright © 2011-2022 走看看