線性表之順序表
順序表使用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;
}