大话数据结构笔记_线性表

线性表的定义 :

  简而言之 : 0 个 或 多个元素(类型相同)的有限序列( 有顺序 ) , 第一个元素无前驱 , 最后一个元素无后继 , 其他元素 与有唯一的前驱 和 唯一的后继
  数学语言定义 : 若将线性表记为 ( a1 , a2 , ..... , ai - 1 , ai , ai+1 , ... , an) , 则表中 ai-1 领先于 ai , ai 领先于 ai+1
           称 ai-1 是 ai 的前驱 , ai+1 是 ai 的后继元素 . 当 i = 1 , 2 ... , n - 1 时候 , ai 有且仅有 一个 直接后
         继 , 当 i = 2 ,......., n 时候 , ai 有且仅有一个直接的前驱。
  线性表的长度 : 线性表的元素的个数 n( n>=0 ) , 当 n = 0 时候 我们称之为空表


线性表的ADT :

  注意 :  这只是 抽象 层面 来说 , 也就是说实现方式尽管 有 顺序表连表等实现方式 , ADT仅仅抽取他们的相同
      处 且 基本具有的操作 , 具体实现时候 , 可以添加Data 数据 , 可以 扩充 操作 或者添加 辅助方法( 抽取
      相同代码 )。 对于实际问题中更复杂的操作 , 可以使用ADT中的基本操作来组合完成。

       定义如下:
    

ADT 线形表 ( List ) 
Data : 下一层数据类型 + 描述
线性表的数据对象的序列 {a1,a2,a3,......, an} , 每个元素均为DataType , 其中 , 除了元素 a1 外 , 每一个    
元素都只有唯一的前驱元素 , 除了an外 , 每个元素都只有唯一的后继元素 。 元素之间的关系是一对一的关 
系。
Operation: 操作 + 描述
(规定 : 提前说明 , 我们使用的编号 均从 0 开始 , 操作返回 0 代表成功 , -1 代表失败)

InitList(*L) : 初始化操作 , 给L 指针指向的List类型开辟能容纳序列的空间
ListEmpty(L) : 若线性表为空 , 返回true else false
ClearList(*L) : 将线性能表清空 
GetElem(L , i ,*e) : 将线性表L中的第i个元素通过传出参数e取出 , 返回值 0 代表的 成功 , -1 代表错误
LocateElem(L,e ) : 将线形表L 中查找 第一个匹配到的e , 成功返回 编号位置 , 失败返回-1
ListInsert(*L , i , e) : 在线性表第 i 个元素 的前面 插入一个元素 , 成功返回 0 失败返回 -1 
ListDelete(*L , i ,*e ): 删除线性表中的第i个位置的元素 , 并用e返回其值
ListLength(L) : 返回线性表中的元素的个数 : 
endADT

线形表的顺序存储结构:

  ADT -> 物理层面 -> 语言实现( C 语言实现):

  指的是使用一段连续的存储单元依次存储线性表的数据元素。

   

sqList 结构体 定义在头文件当中:

#ifndef __SEQ_LIST_H
#define __SEQ_LIST_H

#define MAXSIZE 20     /*假设顺序表的容量为20*/
#define TRUE     0     /*我们只使用TRUE 和 FALSE 两个量表示成功和失败就行了 , 但是注意TRUE是0*/
#define FALSE   -1   
 
typedef int ElemType;  /*假设ElemType 类型为int*/
typedef int BOOL;      /*BOOL 表示两个量 : TRUE | FALSE */
 
/*结构体的声明放在*/
typedef struct
{
     ElemType data[MAXSIZE];
     int length;        /*扩充了ATD的DATA,其表示指向序列最后一个元素的下一个位置*/
}sqList;
  
/*函数的声明放在这个位置 */
extern void InitList(sqList * L);
extern BOOL ListEmpty(sqList L);
extern void ClearList(sqList * L);
extern int LocateElem(sqList L , ElemType e);
extern int  ListLength(sqList L);
extern BOOL ListInsert(sqList * L , int i , ElemType e);
extern BOOL ListDelete(sqList * L , int i , ElemType *e);
extern int GetElem(sqList L , int i  , ElemType * e); 

#endif
sqList 结构体定义 以及 操作接口声明

sqList 操作定义在 .c 文件当中 :

/*************************************************
Function: InitList 
Description: 初始化顺序表的长度为 0 
Output: *L : 线性表发生变动
Return: 空 TRUE | 非空FALSE (TRUE :0  FALSE:-1)
*************************************************/
void InitList(sqList * L)
{
     L->length = 0;
}

/*************************************************
Function: LisEempty
Description: 返回顺序表是否为空 , O(1)
              
              判断 L->length 是否为0即可
 
Input:       L : 线性表结构 
Return: 空 TRUE | 非空FALSE (TRUE :0  FALSE:-1)
*************************************************/
BOOL ListEmpty(sqList L)
{   
    return L.length ? FALSE : TRUE;
}

/*************************************************
Function: ClearList 
Description:  将顺序表清空 O(1) 
              
              将L->length 置为0即可
Output: *L : 线性能表发生变动
Return: void
*************************************************/
void ClearList(sqList * L)
{
    L->length = 0;
}

/*************************************************
Function: LocateElem
Description: 获取第一次出现指定元素的位置 O(n)
            
             开始遍历判断是否相等 
             返回下下标位置
Input:  
        L : 顺序表结构
        e : 指定的元素 
Return: int 具体位置 , 没找到返回-1 
*************************************************/
int LocateElem(sqList L , ElemType e)
{
    int i = 0;
    for(;i < L.length ; ++i)
    {
        if(L.data[i] == e)
            return i;
    }
    return -1;
}

/*************************************************
Function: ListLength 
Description:  获取顺序表的长度 O(1)
                
              直接返回 L.length即可
Input:  L 表结构
Return: int 顺序表的长度
*************************************************/
int ListLength(sqList L)
{
    return L.length;
}

/*************************************************
Function: ListInsert
Description:  
            在顺序表的指定位置插入元素 : 时间复杂度O(n) : 时间浪费在移动上面 : 

            插入位置不合理  , return FALSE
            如果 length + 1 > MAXSIZE  return FALSE
            需要将 i 到 length-1的元素向后移动一个位置
            将元素插入指定位置后 , 表的长度 + 1
Input: 
            i : i位置元素的前面进行插入
            e : 被插入的元素
Output:     
            *L: 传出参数,表示线性表会被修改
Return: 成功 TRUE | 失败 FALSE
*************************************************/
BOOL ListInsert(sqList * L , int i  , ElemType  e)
{
    int j = 0;
    if( 0>i || i > L->length || L->length + 1 > MAXSIZE)
        return FALSE;

    for(j = i+1 ; j <=L->length ; ++j)
        L->data[j] = L->data[j-1];

    L->data[i] = e;
    L->length+=1;

    return TRUE;
}

/*************************************************
Function: ListDelete
Description: 删除指定位置的元素 : O(n) 时间也是浪费在移动数据上面 :

             如果删除的位置不合适: return FALSE
             取出删除的元素
             将 i 位置之后的元素都向前移动一个元素:
             表的长度需要减去 1 
Input:  
        i : 删除元素的位置 :  0<=i<=L->length-1
Output:
        L : 表会发生变动
        e : 输出被删除的元素
Return: 删除成功 TRUE | 失败 FALSE
*************************************************/
BOOL ListDelete(sqList * L , int i , ElemType * e)
{
    int j = 0;
    if(0 == L->length || 0 > i || i >= L->length)
            return FALSE;

    *e = L->data[i];

    for(j = i+1 ; j <=L->length ; ++j)
    {
        L->data[j-1] = L->data[j];
    }

    L->length-=1;
    return TRUE;
}


/*************************************************
Function: GetElem
Description: 获取顺序表中指定位置的元素 , 时间复杂度O(n) , 时间浪费在遍历上面:
            
             i位置不合理 return FALSE
             取得i位置的元素
        
Input: 
      L  : 顺序表结构
      i  : 获取元素的位置 ,  0<= i <= L.length-1 
Output: 
      *e : 输出类型参数 , 获取 i 指向的元素  
Return: 成功TRUE | 失败 FALSE
*************************************************/
BOOL GetElem(sqList L , int i  , ElemType * e)
{
    /* i 是从0 开始计算的*/
    if(0 == L.length || i < 0 || i > L.length-1)
        return FALSE;
    *e = L.data[i];
    return TRUE;
}
sqList 操作的实现

宗上看出:  

  主要操作:
    插入 , 删除 O(n)
    搜寻 , 修改 O(1)

线性能表存储结构的优点和缺点:

  • 优点:
    • 无需为表中元素之间的逻辑关系增加额外空间(比如连表 , 需要增加一个指针域)
    • 可以快速的存取表中 任意元素的位置
  • 缺点:
    • 插入 和 删除操作需要移动大量元素
    • 当线性表的长度变化较大时 , 难以确定存储空间的容量
    • 造成存储空间的碎片 [ 可能开辟的空间大小 > 顺序表的大小造成 空间的浪费 ]

猜你喜欢

转载自www.cnblogs.com/Geek-Z/p/9925475.html
今日推荐