【C语言】静态顺序表和动态顺序表的实现

线性表

定义一张顺序表也就是在内存中开辟一段连续的存储空间,并给它一个名字进行标识。只有定义了一个顺序表,才能利用该顺序表存放数据元素,也才能对该顺序表进行各种操作。

静态顺序表结构如下:

#define MAX_SIZE 100
typedef int DataType;
typedef struct SeqList
{
    DataType array[MAX_SIZE];
    int size;
}SeqList;

静态顺序表的一些基本操作实现如下:

void InitSeqList(SeqList* pSeq)         
{
    assert(pSeq);
    memset(pSeq->array, 0, MAX_SIZE*sizeof(DataType));
    pSeq->size = 0;
}
void PrintSeqList(SeqList* pSeq)          
{
    assert(pSeq);
    int i = 0;
    for (; i < pSeq->size; i++)
    {
        printf("%d ",pSeq->array[i]);
    }
    printf("\n");
}
void PushBack(SeqList* pSeq, DataType data)
{
    assert(pSeq);
    if (pSeq->size == MAX_SIZE)
    {
        printf("Capacity Is Full\n");
        return;
    }
    pSeq->array[pSeq->size++] = data;
}
void PopBack(SeqList* pSeq)
{
    assert(pSeq);
    if (pSeq->size == 0)
    {
        printf("Capacity Is Empty\n");
        return;
    }
    pSeq->size--;
}
void PushFront(SeqList* pSeq,DataType data)
{
    assert(pSeq);
    if (pSeq->size == MAX_SIZE)
    {
        printf("Capacity Is Full\n");
        return;
    }
    int i = pSeq->size - 1;
    for (; i >= 0; i--)
    {
        pSeq->array[i + 1] = pSeq->array[i];
    }
    pSeq->array[0] = data;
    pSeq->size++;
}
void PopFront(SeqList* pSeq)
{
    assert(pSeq);
    if (pSeq->size == 0)
    {
        printf("Capacity Is Empty\n");
        return;
    }
    int i = 0;
    for (; i < pSeq->size - 1; i++)
    {
        pSeq->array[i] = pSeq->array[i + 1];
    }
    pSeq->size--;
}
void Insert(SeqList* pSeq, int index, DataType data)
{
    assert(pSeq);
    if (pSeq->size == MAX_SIZE)
    {
        printf("Capacity Is Full\n");
        return;
    }
    int i = pSeq->size - 1;
    for (; i >= index; i--)
    {
        pSeq->array[i + 1] = pSeq->array[i];
    }
    pSeq->array[index] = data;
    pSeq->size++;
}
void Modified(SeqList* pSeq,int index, DataType data)
{
    assert(pSeq);
    if (index < 0 || index > pSeq->size - 1)
    {
        printf("Invaid Index\n");
        return;
    }
    pSeq->array[index] = data;
}
void Removed(SeqList* pSeq, int index)
{
    assert(pSeq);
    if (index < 0 || index > pSeq->size - 1)
    {
        printf("Invaid Index\n");
        return;
    }
    int i = index;
    for (; i < pSeq->size - 1; i++)
    {
        pSeq->array[i] = pSeq->array[i + 1];
    }
    pSeq->size--;
}

typedef enum TAG
{
    TRUE,
    FALSE,
}TAG;
TAG tag;
typedef struct FindRet
{
    TAG Is_Find;
    int index;
}FindRet;
FindRet ret;

FindRet Find(SeqList* pSeq, DataType data , int index)//从下标index开始查找数据data
{
    assert(pSeq);
    ret.Is_Find = FALSE;
    if (index < 0 || index > pSeq->size - 1)
    {
        printf("Invaid Index\n");
        return ret;
    }
    for (; index < pSeq->size; index++)
    {
        if (pSeq->array[index] == data)
        {
            ret.Is_Find = TRUE;
            ret.index = index;
            return ret;
        }
    }
    return ret;
}
TAG Erase(SeqList* pSeq, DataType data, TAG all)//all=FALSE时删除第一个出现的数据
                                               //all=TURE时删除一个所有相同的数据
{
    assert(pSeq);
    tag = FALSE;
    ret = Find(pSeq,data,0);
    while (ret.Is_Find == TRUE)
    {
        tag = TRUE;
        Removed(pSeq,ret.index);
        if (all == FALSE)
        {
            break;
        }
        ret = Find(pSeq, data, ret.index);
    }
    return tag;
}

动态顺序表结构如下:

#define EXPLAND_CAPACITY 10 //最初容量为10
typedef int DataType;
typedef struct SeqList
{
    DataType* elem; //指向当前空间
    int size;       //当前有效数据的长度
    int capacity;   //当前容量
}SeqList;

动态顺序表的一些基本操作实现如下::


void InitSeqList(SeqList* pSeq)
{
    pSeq->elem = (DataType*)malloc(EXPLAND_CAPACITY*sizeof(DataType));
    pSeq->capacity = EXPLAND_CAPACITY;
    pSeq->size = 0;
}
void PrintSeqList(SeqList* pSeq)
{
    assert(pSeq);
    int i = 0;
    for (; i < pSeq->size; i++)
    {
        printf("%d ", pSeq->elem[i]);
    }
    printf("\n");
}
void Expland_Capacity(SeqList* pSeq)        //扩大容量
{
    assert(pSeq);
    if (pSeq->size == pSeq->capacity)
    {
        pSeq->capacity = pSeq->capacity * 2;
        DataType* newelem = (DataType*)malloc(pSeq->capacity*sizeof(DataType));
        memcpy(newelem, pSeq->elem, pSeq->size*sizeof(DataType));
        free(pSeq->elem);
        pSeq->elem = newelem;
    }
}
void PushBack(SeqList* pSeq, DataType data)
{
    assert(pSeq);
    Expland_Capacity(pSeq);
    pSeq->elem[pSeq->size++] = data;
}
void PopBack(SeqList* pSeq)
{
    assert(pSeq);
    if (pSeq->size > 0)
    {
        pSeq->size--;
    }
}
void PushFront(SeqList* pSeq,DataType data)
{
    assert(pSeq);
    Expland_Capacity(pSeq);
    int i = pSeq->size - 1;
    for (; i >= 0; i--)
    {
        pSeq->elem[i + 1] = pSeq->elem[i];
    }
    pSeq->elem[0] = data;
    pSeq->size++;
}
void PopFront(SeqList* pSeq)
{
    assert(pSeq);
    if (pSeq->size == 0)
    {
        printf("Capacity Is Empty\n");
        return;
    }
    int i = 0;
    for (; i < pSeq->size - 1; i++)
    {
        pSeq->elem[i] = pSeq->elem[i + 1];
    }
    pSeq->size--;
}
void BubbleSort(SeqList* pSeq)     //冒泡排序
{
    assert(pSeq);
    int i, j;
    int count = 0;
    int flag = 0;
    for (i = 0; i < pSeq->size - 1; i++)
    {
        for (j = 0; j < pSeq->size - 1 - i; j++)
        {
            if (pSeq->elem[j]>pSeq->elem[j + 1])
            {
                int tmp = pSeq->elem[j];
                pSeq->elem[j] = pSeq->elem[j + 1];
                pSeq->elem[j + 1] = tmp;
                flag = 1;
                count++;    //计算交换次数
            }
        }
        if (flag == 0)      //如果第一轮比较没有交换过,说明是序列本来是升序的
        {
            printf("count = %d\n", count); 
            break;
        }
        flag = 0;
    }
}
void SeleSort(SeqList* pSeq)    //选择排序
{
    assert(pSeq);
    int i,j,k;
    for (i = 0; i < pSeq->size - 1; i++)
    {
        k = i;
        for (j = i + 1; j < pSeq->size; j++)
        {
            if (pSeq->elem[k] > pSeq->elem[j])
            {
                k = j;
            }
        }
        if (k != i)
        {
            int tmp = pSeq->elem[k];
            pSeq->elem[k] = pSeq->elem[i];
            pSeq->elem[i] = tmp;
        }
    }
}
int BinarySearch(SeqList* pSeq,DataType data)       //二分查找
{
    assert(pSeq);
    int lift = 0;
    int right = pSeq->size - 1;
    int mid = lift + (right - lift) / 2;//防止相加发生溢出
    while (lift <= right)
    {
        mid = lift + (right - lift) / 2;
        if (pSeq->elem[mid] == data)
        {
            return mid;
        }
        else if (pSeq->elem[mid] > data)
        {
            right = mid - 1;
        }
        else
        {
            lift = mid + 1;
        }
    }
    return -1;
}

线性表优点是:

无须为表示表中元素之间的逻辑关系增加额外的存储空间;

可以方便地随机访问表中任一位置的元素。

缺点是:

插入和删除运算不方便,除表尾的位置外,在表的其他位置上进行插入或删除操作都必须移动大量元素,其效率较低;

由于数组要求占用连续的存储空间,存储分配只能预先进行静态分配。因此,当表长变化较大时,难以确定数组的合适的大小。确定大了将造成浪费。

你可能感兴趣的:(【C语言】基础)