数据结构之线性表

线性表

线性表(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("\t%d", *(pL->elem + i));
    }
    printf("\n");
}

//---------------------------------------------------
//测试
#include <stdio.h>
#include "SqList.h"
int main()
{
    //printf("hello world.\n");
    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\n", 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

 

posted @ 2020-07-11 16:48  htj10  阅读(183)  评论(0编辑  收藏  举报
TOP