1. 程式人生 > >C資料結構-線性表之順序表

C資料結構-線性表之順序表

線性表之順序表

順序表使用C語言的原生陣列作為儲存結構,使用者指定陣列的大小,動態的申請堆空間。動態設計的好處比事先用巨集定義規定大小更加靈活,而且支援順序表的重置大小操作。使得使用順序表的人擁有更大的靈活性,節省執行記憶體。順序表結構體的定義使用了柔性陣列,這一點使得我們在操作順序表資料陣列時變得相當簡單。值得講解的有幾個操作:

1. 線性表的重置大小

int seq_list_resize(seq_list *plist, int size);
重置大小可以是容量變大或者變小,如果重置的大小與原陣列的大小一致,那將什麼都不做。重置大小之後將會複製舊陣列中的內容到新的陣列中,實質就是呼叫了realloc函式進行重置和複製工作。如果重置的大小小於原來的大小,那麼將發生資料截斷;如果重置的大小大於原來的大小則原來陣列中的所有元素會被保留。

2. 線性表的清空

int seq_list_clear(seq_list *plist);
清空資料表的操作,實際上只是將順序表的長度值設定為0,並不實際清除陣列中的內容,因為這麼做毫無意義。
#ifndef SEQLIST_H
#define SEQLIST_H

#ifndef NULL
#define NULL 0
#endif


/* 元素型別 */
typedef int elem_t;

/* 順序表結構體 */
typedef struct _tag_list
{
    int length;//順序表長度
    int capacity;//順序表的最大容量
    elem_t data[];

}seq_list;

/*
 * 順序表初始化
 * @param size 順序表的大小
 * @param return 順序表的指標
 */
seq_list *seq_list_init(int size);

/*
 * 插入元素
 * @param plist 順序表指標
 * @param i 插入位置的索引
 * @param e 插入的元素指標
 * @return 1:成功 0:失敗
 */
int seq_list_insert(seq_list *plist,int i,elem_t *pe);

/*
 * 刪除元素
 * @param plist 順序表指標
 * @param i 刪除位置的索引
 * @param pe 儲存被刪除元素值的指標
 * @return 1:成功 0:失敗
 */
int seq_list_delete(seq_list *plist,int i,elem_t *pe);

/*
 * 獲取元素
 * @param plist 順序表指標
 * @param i 獲取位置的索引
 * @param pe 儲存元素值的指標
 * @return 1:成功 0:失敗
 */
int seq_list_get(seq_list *plist,int i,elem_t *pe);

/*
 * 重置順序表大小
 * @param plist 順序表指標
 * @param size 重置後順序表的最大容量
 * @param return 1:成功 0:失敗
 */
int seq_list_resize(seq_list *plist, int size);

/*
 * 判斷順序表是否為空
 * @param plist 順序表指標
 * @return 1:為空 0:不為空
 * @return 1:為空 0:不為空 -1:出錯
 */
int seq_list_is_empty(seq_list *plist);

/*
 * 獲取順序表的長度
 * @param plist 順序表指標
 * @return 長度
 */
int seq_list_length(seq_list *plist);

/*
 * 獲取順序表的最大容量
 * @param plist 順序表指標
 * @return 長度
 */
int seq_list_max_size(seq_list *plist);

/*
 * 清空順序表
 * @param plist 順序表指標
 * @param return 1:成功 0:失敗
 */
int seq_list_clear(seq_list *plist);

/*
* 銷燬順序表
*/
int seq_list_destroy(seq_list *plist);


#endif // SEQLIST


#include "SeqList.h"
#include "malloc.h"

/*
 * 順序表初始化
 * @param size 順序表的大小
 * @param return 順序表的指標
 */
seq_list *seq_list_init(int size)
{
    seq_list *plist = (seq_list *)malloc(sizeof(seq_list) + sizeof(elem_t) * size);

    if(plist)
    {
        plist->length = 0;
        plist->capacity = size;
    }

    return plist;

}

/*
 * 插入元素
 * @param plist 順序表指標
 * @param i 插入位置的索引
 * @param e 插入的元素指標
 * @return 1:成功 0:失敗
 */
int seq_list_insert(seq_list *plist,int i,elem_t *pe)
{
    //合法性檢查
    int ret = ( (plist != NULL) && (i >= 0) && (i <= plist->length) && (plist->length + 1 <= plist->capacity) );

    if(ret)
    {
        int pos =0;
        //從後往前逐個將元素後移
        for(pos = plist->length;pos > i;pos--)
        {
            plist->data[pos] = plist->data[pos - 1];
        }
        //將元素插入
        plist->data[i] = *pe;
        plist->length++;
    }

    return ret;
}

/*
 * 刪除元素
 * @param plist 順序表指標
 * @param i 刪除位置的索引
 * @param pe 儲存被刪除元素值的指標
 * @return 1:成功 0:失敗
 */
int seq_list_delete(seq_list *plist,int i,elem_t *pe)
{
    //合法性檢查
    int ret = ( (plist != NULL) && (i >= 0) && (i < plist->length) );

    if(ret)
    {
        int pos = 0;
        //儲存被刪除元素的值
        *pe = plist->data[i];
        //從被刪除索引處開始,將後一位的資料往前移動
        for(pos = i;pos < plist->length -1;pos++)
        {
            plist->data[pos] = plist->data[pos + 1];
        }
        plist->length--;


    }

    return ret;
}

/*
 * 獲取元素
 * @param plist 順序表指標
 * @param i 獲取位置的索引
 * @param pe 儲存元素值的指標
 * @return 1:成功 0:失敗
 */
int seq_list_get(seq_list *plist,int i,elem_t *pe)
{
    //合法性檢查
    int ret = ( (plist != NULL) && (i >= 0) && (i < plist->length) );

    if(ret)
    {
        //儲存元素的值
        *pe = plist->data[i];

    }

    return ret;
}

/*
 * 判斷順序表是否為空
 * @param plist 順序表指標
 * @return 1:為空 0:不為空 -1:出錯
 */
int seq_list_is_empty(seq_list *plist)
{
    int ret = -1;

    if(plist != NULL)
    {
        ret = (plist->length == 0);
    }
    return ret;
}

/*
 * 獲取順序表的長度
 * @param plist 順序表指標
 * @return 長度,-1出錯
 */
int seq_list_length(seq_list *plist)
{
    int ret = -1;

    if(plist != NULL)
    {
        ret = plist->length;
    }

    return ret;
}

/*
 * 重置順序表大小
 * @param plist 順序表指標
 * @param size 重置後順序表的最大容量
 * @param return 1:成功 0:失敗
 */
int seq_list_resize(seq_list *plist, int size)
{
    int ret = (plist != NULL && size >0);

    if(ret && (plist->length != size) )
    {
        int length = plist->length;
        length = (size > length ? length : size);
        //重新申請空間,realloc會自動釋放原空間
        seq_list *p = realloc(plist,sizeof(seq_list) + sizeof(elem_t) * size);
        if(p != NULL)
        {
            plist = p;
            plist->length = length;
            plist->capacity = size;
        }else
        {
            ret = 0;
        }
    }

    return ret;
}

/*
 * 獲取順序表的最大容量
 * @param plist 順序表指標
 * @return 長度,-1出錯
 */
int seq_list_max_size(seq_list *plist)
{
    int ret = -1;

    if(plist != NULL)
    {
        ret = plist->capacity;
    }

    return ret;
}

/*
 * 清空順序表
 * @param plist 順序表指標
 * @param return 1:成功 0:失敗
 */
int seq_list_clear(seq_list *plist)
{
    int ret = (plist != NULL);

    if(ret)
    {
        plist->length = 0;
    }

    return ret;
}

/*
* 銷燬順序表
*/
int seq_list_destroy(seq_list *plist)
{
    int ret = (plist != NULL);

    if(ret)
    {
        free(plist);
        plist = NULL;
    }

    return ret;
}