线性表(List): 零个或多个数据元素的有序序列。简而言之,一个线性表是n个数元素的有限序列。至于每个数据元素的具体含义,在不同的情况下各有不同,可以是一个数字或一个符号,也可以是一本书,甚至其他更复杂的信息。
线性结构的特点:在数据元素的非空有限集中
数学语言定义线性表:
若将线性表记作:
( a 1 , . . . , a i − 1 , a i , a i + 1 , . . . , a n ) (a_1,...,a_{i-1},a_i,a_{i+1},...,a_n) (a1,...,ai−1,ai,ai+1,...,an)
则表示 a i − 1 a_{i-1} ai−1 领先于 a i a_i ai , a i a_i ai 领先于 a i + 1 a_{i+1} ai+1 ,称 a i − 1 a_{i-1} ai−1 是 a i a_i ai 的直接前驱元素, a i + 1 a_{i+1} ai+1 是 a i a_i ai 的直接后继元素。当 i = 1 , 2 , . . . , n − 1 i=1,2, ... , n-1 i=1,2,...,n−1 时, a i a_i ai 有且只有一个后继元素,当 i = 2 , 3 , . . . , n i=2,3, ... ,n i=2,3,...,n 时, a i a_i ai 有且仅有一个直接前驱。
线性表中的元素个数 n ( n ≧ 0 ) n(n\geqq0) n(n≧0) 定义为线性表的长度, n = 0 n=0 n=0 时表示为空表。在非空表中的每个元素都有一个确定的位置,如 a 1 a_1 a1 是第一个数据元素, a n a_n an 是最后一个数据元素, a i a_i ai 是第 i i i 个数据元素,称 i i i 为数据元素 a i a_i ai 在 线性表中的位序。
线性表的顺序存储结构,指定是用一段地址连续的存储单元依次存储线性表的数据元素。
定义头文件声明数据结构与方法:
#ifndef __MY_SEQLIST_H__
#define __MY_SEQLIST_H__
#define TRUE 1
#define FALSE 0
#define SEQLIST_NULL_ERR (100)
#define SEQLIST_POS_ERR (SEQLIST_NULL_ERR+1)
#define SEQLIST_FULL_ERR (SEQLIST_NULL_ERR+2)
#define SEQLIST_LENGTH_ERR (SEQLIST_NULL_ERR+3)
typedef void SeqList; //定义线性表数据结构
typedef void SeqListNode; //定义线性表节点元素
/************************************************************************
根据指定内存大小分配链表内存空间
----------------------------------------------------------------------
参数 :int capacity 内存空间大小
返回值 :SeqList* | NULL
************************************************************************/
SeqList*
SeqList_Create_null (int capacity);
/************************************************************************
释放链表内存空间
------------------------------------------------------------------------
参数 :SeqList* list 链表内存地址
返回值 :void
************************************************************************/
void
SeqList_Destroy (SeqList* list);
/************************************************************************
清除链表元素
------------------------------------------------------------------------
参数 :SeqList* list 链表内存地址
返回值 :void
************************************************************************/
void
SeqList_Clear (SeqList* list);
/************************************************************************
获取链表元素个数
------------------------------------------------------------------------
参数 :SeqList* list
返回值 :链表实际元素个数 | 0
************************************************************************/
int
SeqList_Length (SeqList* list);
/************************************************************************
获取链表空间字节大小
------------------------------------------------------------------------
参数 :SeqList* list
返回值 :链表实际空间大小 | 0
************************************************************************/
int
SeqList_Capacity (SeqList* list);
/************************************************************************
链表插入元素节点
------------------------------------------------------------------------
参数 :SeqList* list 链表指针
SeqListNode* node 元素节点
int pos 插入元素位置
返回值 : 1 (TRUE) | ERR (Type)
************************************************************************/
int
SeqList_Insert (SeqList* list, SeqListNode* node, int pos);
/************************************************************************
获取链表指定位置元素
------------------------------------------------------------------------
参数 :SeqList* list 链表指针
int pos 下标位置
返回值 :NULL | SeqListNode*
************************************************************************/
SeqListNode*
SeqList_Get (SeqList* list, int pos);
/************************************************************************
删除链表指定位置的元素
------------------------------------------------------------------------
参数 :SeqList* list 链表指针
int pos 元素下标位置
返回值 :NULL | SeqListNode*
************************************************************************/
SeqListNode*
SeqList_Delete (SeqList* list, int pos);
#endif //__MY_SEQLIST_H__
实现方法:
#include
#include
#include
#include "SeqList.h"
/*线性表内部结构*/
typedef struct _SeqList
{
//链表长度
int length;
//链表容量
int capacity;
//链表数据指针(存储元素地址集合)
unsigned int **node;
}TSeqList;
//创建链表
SeqList* SeqList_Create_null ( int capacity )
{
TSeqList* temp = NULL;
temp = (TSeqList*) malloc (sizeof (TSeqList));
if (temp==NULL)
{
printf ("Function: SeqList_Create_null() err =%d ! \n", SEQLIST_NULL_ERR);
return NULL;
}
memset (temp, 0x00, sizeof (TSeqList));//初始化内存
temp->node = (unsigned int **) malloc (sizeof (unsigned int*)*capacity);
if (temp->node==NULL)
{
printf ("Function: SeqList_Create_null() err =%d ! \n", SEQLIST_NULL_ERR);
return NULL;
}
temp->length = 0;
temp->capacity = capacity;
return temp;
}
//释放链表空间
void SeqList_Destroy (SeqList* list)
{
TSeqList * temp = NULL;
if (list==NULL)
{
return;
}
temp = (TSeqList *) list;
if (temp->node!=NULL)
{
free (temp->node);
temp->node = NULL;
}
free (temp);
temp = NULL;
return;
}
//清空链表
void SeqList_Clear (SeqList* list)
{
TSeqList* temp = NULL;
if (list==NULL)
{
return;
}
temp = (TSeqList*) list;
temp->length = 0;
}
//获取链表元素个数
int SeqList_Length (SeqList* list)
{
TSeqList* temp = NULL;
if (list==NULL)
{
return 0;
}
temp = (TSeqList*) list;
return temp->length;
}
//获取链表空间大小
int SeqList_Capacity (SeqList* list)
{
TSeqList* temp = NULL;
if (list == NULL)
{
return 0;
}
temp = (TSeqList*) list;
return temp->capacity;
}
//链表指定位置插入元素
int SeqList_Insert (SeqList* list, SeqListNode* node, int pos)
{
int ret = 0, i = 0;
TSeqList* listTmp = NULL;
if (list==NULL||node==NULL)
{
ret = SEQLIST_NULL_ERR;
return ret;
}
listTmp = (TSeqList*) list;
//判断链表是否已满
if (listTmp->length >= listTmp->capacity)
{
ret = SEQLIST_FULL_ERR;
return ret;
}
if (pos < 0 || pos>listTmp->capacity)
{
ret = SEQLIST_POS_ERR;
return ret;
}
//容错修正 如果给定插入位置超出现有 length 则 pos = length
if (pos>=listTmp->length)
{
pos = listTmp->length;
}
//元素向后移动
for (i = listTmp->length; i < pos;i--)
{
listTmp->node[i] = listTmp->node[i - 1];
}
//元素插入
listTmp->node[i] = node;
listTmp->length++;//元素个数加1
return TRUE;
}
//获取指定位置元素
SeqListNode* SeqList_Get (SeqList* list, int pos)
{
int i = 0;
TSeqList* listTmp = NULL;
SeqListNode* ret = 0;
if (list==NULL)
{
printf ("Function: SeqList_Get() err =%d ! \n", SEQLIST_NULL_ERR);
return NULL;
}
listTmp = (TSeqList*) list;
if (pos < 0 || pos>listTmp->length)
{
printf ("Function: SeqList_Get() err =%d ! \n", SEQLIST_POS_ERR);
return NULL;
}
ret = (SeqListNode*) ( listTmp->node[pos] );
return ret;
}
//删除链表指定位置元素
SeqListNode* SeqList_Delete (SeqList* list, int pos)
{
int i = 0;
TSeqList* listTmp = NULL;
SeqListNode* ret = 0;
if (list==NULL)
{
printf ("Function: SeqList_Delete() err =%d ! \n", SEQLIST_NULL_ERR);
return NULL;
}
listTmp = (TSeqList*) list;
if (pos<0||pos>=listTmp->length)
{
printf ("Function: SeqList_Delete() err =%d ! \n", SEQLIST_POS_ERR);
return NULL;
}
ret = (SeqListNode*) listTmp->node[pos];
for (i = pos + 1; i < listTmp->length;i++)
{
listTmp->node[i - 1] = listTmp->node[i];//元素向前移动
}
listTmp->length--;//元素个数减1
return ret;
}
调用:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include "SeqList.h"
typedef struct _User_info
{
int age;
char name[16];
}User;
int main (void)
{
int ret = 0;
int i = 0;
User u1, u2, u3, u4, u5, u6;
{
u1.age = 11;
u2.age = 12;
u3.age = 13;
u4.age = 14;
u5.age = 15;
u6.age = 16;
strcpy (u1.name, "AAA");
strcpy (u2.name, "BBB");
strcpy (u3.name, "CCC");
strcpy (u4.name, "DDD");
strcpy (u5.name, "EEE");
strcpy (u6.name, "FFF");
}
SeqList* list = NULL;
list = SeqList_Create_null (10);
if (list==NULL)
{
printf ("链表初始化失败!\n");
return 0;
}
//插入
ret = SeqList_Insert (list, (SeqListNode*) &u1, 0);
ret = SeqList_Insert (list, (SeqListNode*) &u2, 1);
ret = SeqList_Insert (list, (SeqListNode*) &u3, 2);
ret = SeqList_Insert (list, (SeqListNode*) &u4, 3);
ret = SeqList_Insert (list, (SeqListNode*) &u5, 4);
ret = SeqList_Insert (list, (SeqListNode*) &u6, 5);
//获取链表元素个数
printf ("list 链表元素个数=%d \n", SeqList_Length (list));
//遍历
for (i = 0; i < SeqList_Length (list);i++)
{
User* u = (User*) SeqList_Get (list, i);
if (u==NULL)
{
printf ("获取元素失败! %d\n",i);
return 0;
}
printf ("age=%d ; name=%s \n", u->age, u->name);
}
//链表元素
SeqList_Clear (list);
//获取链表元素个数
printf ("list 链表元素个数=%d \n", SeqList_Length (list));
User u7, u8, u9, u10, u11, u12;
{
u7.age = 111;
u8.age = 112;
u9.age = 113;
u10.age = 114;
u11.age = 115;
u12.age = 116;
strcpy (u7.name, "MMM");
strcpy (u8.name, "NNN");
strcpy (u9.name, "QQQ");
strcpy (u10.name, "YYY");
strcpy (u11.name, "PPP");
strcpy (u12.name, "LLL");
}
ret = SeqList_Insert (list, (SeqListNode*) &u7, 0);
ret = SeqList_Insert (list, (SeqListNode*) &u8, 1);
ret = SeqList_Insert (list, (SeqListNode*) &u9, 2);
ret = SeqList_Insert (list, (SeqListNode*) &u10, 3);
ret = SeqList_Insert (list, (SeqListNode*) &u11, 4);
ret = SeqList_Insert (list, (SeqListNode*) &u12, 5);
printf ("list 链表元素个数=%d \n", SeqList_Length (list));
//遍历
for (i = 0; i < SeqList_Length (list); i++)
{
User* u = (User*) SeqList_Get (list, i);
if (u == NULL)
{
printf ("获取元素失败! %d\n", i);
return 0;
}
printf ("age=%d ; name=%s \n", u->age, u->name);
}
//获取指定位置元素:
User* up=(User*) SeqList_Get (list, 4);
printf ("age=%d ; name=%s \n", up->age, up->name);
//删除指定位置元素
SeqList_Delete (list, 4);
printf ("删除了元素后 list 链表元素个数=%d \n", SeqList_Length (list));
SeqList_Destroy (list);
if (list==NULL)
{
printf ("链表空间以释放!\n");
}
system ("PAUSE");
return 0;
}
优点:
缺点: