数据结构--顺序表简单实现(总结)

Posted 庸人冲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构--顺序表简单实现(总结)相关的知识,希望对你有一定的参考价值。

在这里插入图片描述

特点

  1. 顺序表是有序有限,且元素数据类型相同的集合。
  2. 除第一个元素外,其他元素都有唯一的前驱元素
  3. 除最后一个元素外,其他的元素都有唯一的后继元素
  4. 顺序表中的元素总数n(n ≥ 0)即为顺序表的长度n = 0时,顺序表的长度为0,为空表。

功能实现

定义

#define SUC 1   		// 定义SUC 作为状态返回值,成功
#define ERR 0   		// 定义ERR 作为状态返回值,错误
#define TRUE 1  		// 定义TRUE 作为真假返回值,真
#define FALSE 0 		// 定义FALSE 作为真假返回值,假
#define MAXSIZE 20 		// 定义MAXSIZE为存储空间最大容量,依据情况而定

typedef int Status;     // 定义Status作为状态返回类型
typedef int Bool;       // 定义Bool 作为判断真假返回类型
typedef int ElemType ;  // ElemType 表示表中元素数据类型,依据情况而定
typedef struct       	// 定义存储结构
{
    ElemType data[MAXSIZE];   // 定义数组,作为顺序表的存储结构
    int len; 				// 定义len,表示【顺序表】长度
} SqList;

函数

初始化

功能:将顺序表长度初始化为0。

参数类型:SqList*

返回值类型:Status

Status InitList(SqList* L)
{
    L->len = 0;
    return SUC;
}

重置表

功能:将顺序表长度重置为0,置为空表,该操作是对于以创建顺序表的操作。

参数类型:SqList*

返回值类型:Status

Status ResetList(SqList* L)
{
    L->len = 0;
    return SUC;
}

获取表长

功能:获取顺序表的长度。

参数类型:SqList

返回值类型:int

int ListLength(SqList L)
{
    return L.len;
}

判断是否为空表

功能:判断顺序表是否为空表

参数类型:SqList

返回值类型:Bool

Bool isEmpty(SqList L)
{
    return L.len == 0 ? TRUE : FALSE;
}

访问元素

功能:输出指定元素至控制台

参数类型:ElemType

返回值类型:Status

Status visit(ElemType e)
{
    printf("%d ",e);
    return SUC;
}

遍历顺序表

功能:遍历顺序表中每个元素

参数类型:SqList

返回值类型:Status

Status ListTraverse(SqList L)
{
    int i = 0;
    int len = L.len;
    for(i = 0; i < len; i++)
    {
		visit(L.data[i]);
    }
    printf("\\n");
    return SUC;
}

获取元素

功能:将指定位置上的元素的值赋值给接收元素

参数类型:SqListElemType*(接收元素)、int(位置)

返回值:Status

说明:

  1. 判断顺序表是否为空表?为空表返回ERR
  2. 判断指定位置是否合法?非法返回ERR
Status GetElem(SqList L, ElemType* e, int p)
{
    if(L.len == 0 || p < 1 || p > L.len)
    {
		return ERR;
    }
    *e = L.data[p - 1];
    return SUC;
}

查找元素

功能:查找指定元素在顺序表中的位置

参数类型:SqListElemType

返回值:int

说明:

  1. 判断顺序表是否为空表,空表返回0
  2. 遍历顺序表查找到则返回该位置,否则返回0
int LocataElem(SqList L, ElemType e)
{
    if(L.len == 0)
    {
        return 0;                  // 空表返回0 
    }
    int i = 0;
    for(i = 0; i < L.len; i++)
    {
        if(L.data[i] == e)
            return i + 1;         // 找到则返回位置
    }
    return 0;                     // 找不到则返回0
}

头插

功能:将元素添加至顺序表头。

参数类型:SqList*ElemType(添加的元素)

返回值类型:Status

说明:

  1. 判断顺序表是否已满
  2. 将所有元素整体后移一位
  3. 将元素添加至表头,表长+1
Status PushFront(SqList* L, ElemType e)
{
    int i = 0;        
    if (L->len == MAXSIZE)                // 判断顺序表是否已满
    {
        return ERR;
    }
    for (i = L->len - 1; i >= 0; i--)    
    {
        L->data[i + 1] = L->data[i];     // 将所有元素整体后移一位
    }
    L->data[0] = e;                      // 将元素添加至表头
    L->len++;                            // 表长+1
    return SUC;
}

尾插

功能:判断将元素添加至表尾

参数类型:SqList*ElemType(添加的元素)

返回值类型:Status

说明:

  1. 判断顺序表是否已满
  2. 将元素添加至表尾,表长+1
Status PushBack(SqList* L, ElemType e)
{
    if (L->len == MAXSIZE)                
    {
        return ERR;                      // 顺序表已满,则返回ERR
    }
                     
    L->data[L->len] = e;                 // 将元素添加至尾部,L->len是顺序表最后一个元素后一个位置,即表尾
    L->len++;                            // 顺序表长度+1
    return SUC;
}

指定位置插入元素

功能:将元素添加至顺序表中指定位置。

参数类型:SqList*ElemType(添加的元素)、int(位置)

返回值类型:Status

说明:

在添加元素前需要判断三点:

  1. 当前顺序表是否已满?

  2. 添加的位置是否不合理?

  3. 判断添加的位置是否在表尾?

    如果在表尾添加元素则不需要移动表中其他元素,否则需要将添加位置后的所有元素整体向后移动一位(包括添加位置的当前元素)。

添加完毕后,将表长+1,返回SUC

Status InsertPos(SqList* L, ElemType e, int p)
{
    if (L->len == MAXSIZE || p < 1 || p > L->len + 1)  // 判断顺序表是否已满,或则插入位置是否合理
    {                                                  //   L->len+1, 连续线性表,中间不能存在空位置
        return ERR;                 
    }
    if (p <= L->len)   			                     // 判断添加位置是否在表尾,表尾不需要移动表中其他元素
    {   // 进入语句,说明p不在表尾
        int i = 0;                   
        for (i = L->len - 1; i >= p - 1; i--)
        {
            L->data[i + 1] = L->data[i];             // 则需要将添加位置后的所有元素向后移动一位
        }
    }

    L->data[p - 1] = e;                               // 将指定元素添加到指定位置
    L->len++;                                         // 表长+1
    return SUC;
}

头删

功能:将顺序表头的元素删除

参数类型:SqList*ElemType*(接收删除的元素)

返回值类型:Status

说明:

  1. 判断表是否为空,为空返回ERR;
  2. 将顺序表说有元素整体前移一位
  3. 顺序表长度-1
Status PopFront(SqList* L, ElemType* e)
{
    if (L->len == 0)
        return ERR;                       // 顺序表为空,返回ERR
    *e = L->data[0];                      // 将被删除的元素赋值给*e
    int i = 0;
    for (i = 0; i < L->len - 1; i++)
    {
        L->data[i] = L->data[i + 1];       // 将所有元素整体前移一位
    }
    L->len--;                              // 顺序表长度减1
    return SUC;                            // 返回SUC
}

尾删

功能:将顺序表尾的元素删除

参数类型:SqList*ElemType*(接收删除的元素)

返回值类型:Status

说明:

  1. 判断表是否为空,为空返回ERR
  2. 变量接收被删除的元素
  3. 顺序表长度-1
Status PopBack(SqList* L, ElemType* e)
{
    if (L->len == 0)
        return ERR;                       // 顺序表为空,返回ERR
    *e = L->data[L->len - 1];             // 被删除的元素赋值给*e, L->len - 1为最后一个元素的下标
    L->len--;                             // 将表长-1,达到删除表尾元素目的
    return SUC;
}

指定位置删除元素

功能:删除顺序表指定位置元素

参数类型:SqList*ElemType*(接收删除的元素)、int(指定删除的位置)

返回值类型:Status

说明:

  1. 判断表是否为空,或者删除位置是否合法,如果为真,则返回ERR。
  2. 将被删除的元素赋值给外部变量。
  3. 判断删除位置是否为最后一个元素,若不是是最后一个元素则将删除位置后的所有元素整体前移一位。
  4. 顺序表长度-1。
  5. 返回SUC。
Status DeletePos(SqList* L, ElemType* e, int p)
{

    if (L->len == 0 || p < 1 || p > L->len)     // 判断表是否为空,或者位置是否合法
        return ERR;
    *e = L->data[p - 1];                       // 将被删除的元素赋值给*e
    if (p < L->len)                            // 判断删除位置是否为最后一个元素
    {
        int i = 0;
        for (i = p; i < L->len; i++)
        {
            L->data[i - 1] = L->data[i];      // 若不是最后一个元素则将删除位置后的所有元素整体前移一位
        }
    }
    L->len--;
    return SUC;
}

指定元素删除

功能:将指定的元素从顺序表中删除

参数类型:SqList*ElemType(指定删除元素)

返回值类型:Status

说明:

  1. 调用LocataElem() 函数获取指定元素的位置
  2. 如果LocataElem() 的返回值不为 0,调用DeletePos() 函数将指定元素删除,并返回SUC
  3. 否则返回ERR;
Status DeleteElem(SqList* L, ElemType* e)
{
    int p = LocataElem(*L, *e);            
    if (p)
    {
        DeletePos(L, e, p);
        return SUC;
    }
    return ERR;
}

合并表

功能:将存在于表b,不存在于表a的元素,添加进表a末尾

参数类型:SqList*SqList

返回值类型:void

说明:

  1. 访问表b中的问一个元素,需要用到GetElem()函数。
  2. 将获取的元素与La中的每一个元素进行对比。需要用到LocateElem()
  3. LocateElem()的返回值为0,则说明La中不存在这个元素。
  4. 调用PushBack()函数,将该元素添加至La表尾.
void UnionList(SqList* La, SqList Lb)
{
    ElemType e;                    // 元素e 用来比较两表中是否存在元素e
    // 获取两个表的长度
    int La_len = La->len;
    int Lb_len = Lb.len;
    int i = 0;
    for (i = 1; i <= Lb_len; i++)    // 获取Lb中的每一个元素
    {
        GetElem(Lb, &e, i);
        if (!LocataElem(*La, e))   // 如果La中没有该元素,将该元素添加至表尾。
        {
            PushBack(La, e);
        }
    }
}

测试代码

#define SUC 1   		// 定义SUC 作为状态返回值,成功
#define ERR 0   		// 定义ERR 作为状态返回值,错误
#define TRUE 1  		// 定义TRUE 作为真假返回值,真
#define FALSE 0 		// 定义FALSE 作为真假返回值,假
#define MAXSIZE 20 		// 定义MAXSIZE为存储空间最大容量,依据情况而定

typedef int Status;     // 定义Status作为状态返回类型
typedef int Bool;       // 定义Bool 作为判断真假返回类型
typedef int ElemType ; 	// ElemType 表示表中元素数据类型,依据情况而定
typedef struct       	// 定义存储结构
{
    ElemType data[MAXSIZE];    // 定义数组,作为线性表的存储结构
    int len; 				  // 定义len,表示【线性表】长度
} SqList;


// 初始化
Status InitList(SqList* L)
{
    L->len = 0;              // 将表长初始化为0,该操作是是对于新创建的表
    return SUC;              
}

// 重置表                   
Status ResetList(SqList* L)
{
    L->len = 0;              //  将顺序表长度重置为0,置为空表,该操作是对于以创建顺序表的操作。
    return SUC;
}

// 判断是否为空表
Bool isEmpty(SqList L)
{
    return L.len == 0 ? TRUE : FALSE;   
}

// 获取表长
int ListLength(SqList L)
{
    return L.len;          
}


// 访问元素
Status visit(ElemType e)
{
    printf("%d ", e);            // 打印元素
    return SUC;
}

// 遍历表
Status ListTraverse(SqList L)
{
    int i = 0;
    int len = L.len;
    for (i = 0; i < len; i++)   
    {
        visit(L.data[i]);       // 调用visit函数依次打印顺序表中的元素
    }
    printf("\\n");
    return SUC;
}


// 获取元素
Status GetElem(SqList L, ElemType* e, int p)
{
    if (L.len == 0 || p < 1 || p > L.len)
    {
        return ERR;          // 空表,或位置不合法返回ERR
    }
    *e = L.data[p - 1];      // 将指定位置的元素赋值给e,e为真正的返回值
    return SUC;              // SUC为返回的状态
}

// 查找元素
int LocataElem(SqList L, ElemType e)
{
    if (L.len == 0)
    {
        return 0;                  // 空表返回0 
    }
    int i = 0;
    for (i = 0; i < L.len; i++)
    {
        if (L.data[i] == e)
            return i + 1;         // 找到则返回位置
    }
    return 0;                     // 找不到则返回0
}

// 头插
Status PushFront(SqList* L, ElemType e)
{
    int i = 0;        
    if (L->len == MAXSIZE)                
    {
        return ERR;                       // 顺序表已满,则返回ERR
    }
    for (i = L->len - 1; i >= 0; i--)    
    {
        L->data[i + 1] = L->data[i];     // 将所有元素整体后移一位
    }
    L->data[0] = e;                      // 将元素添加至表头
    L->len++;                            // 表长+1
    return SUC;
}

// 尾插
Status PushBack(SqList* L, ElemType e)
{
    if (L->len == MAXSIZE)                
    {
        return ERR;                      // 顺序表已满,则返回ERR
    }
                     
    L->data[L->len] = e;                 // 将元素添加至尾部,L->len是顺序表最后一个元素后一个位置,即表尾
    L->len++;                            // 顺序表长度+1
    return SUC;
}

// 按位置插入
Status InsertPos(SqList* L, ElemType e, int p)
{
    if (L->len == MAXSIZE || p < 1 || p > L->len + 1)  // 判断顺序表是否已满,或则插入位置是否合理
    {                                                  //   L->len+1, 连续线性表,中间不能存在空位置
        return ERR;
    }
    if (p <= L->len)   			                     // 判断添加位置是否在表尾,表尾不需要移动表中其他元素
    {   // 进入语句,说明p不在表尾
        int i = 0;
        for (i = L->len - 1; i >= p - 1; i--)
        {
            L->data[i + 1] = L->data[i];             // 则需要将添加位置后的所有元素向后移动一位
        }
    }

    L->data[p - 1] = e;                               // 将指定元素添加到指定位置
    L->len++;                                         // 表长+1
    return SUC;
}


// 头删
Status PopFront(SqList* L, ElemType* e)
{
    if (L->len == 0)
        return ERR;                       // 顺序表为空,返回ERR
    *e = L->data[0];                      // 将被删除的元素赋值给*e
    int i = 0;
    for (i = 0; i < L->len - 1; i++)
    {
        L->data[i] = L->data[i + 1];       // 将所有元素整体前移一位
    }
    L->len--;                             // 顺序表长度减1
    return SUC;                           // 返回SUC
}

// 头删
Status PopBack(SqList* L, ElemType* e)
{
    if (L->len == 0)
        return ERR;                       // 顺序表为空,返回ERR

    *e = L->data[L->len - 1];             // 被删除的元素赋值给*e, L->len - 1为最后一个元素的下标
    L->len--;                             // 将表长-1,达到删除表尾元素目的
    return SUC;
}



// 指定位置删除
Status DeletePos(SqList* L, ElemType* e, int p)
{

    if (L->len == 0 || p < 1 || p > L->len)     // 判断表是否为空,或者位置是否合法
        return ERR;
    *e = L->data[p - 1];                       // 将被删除的元素赋值给*e
    if (p < L->len)                            // 判断删除位置是否为最后一个元素
    {
        int i = 0;
        for (i = p; i < L->len; i++)
        {
            L->data[i - 1] = L->data[i];      // 若不是最后一个元素则将删除位置后的所有元素整体前移一位
        }
    }
    L->len--;
    return SUC;
}

// 指定元素删除
Status DeleteElem(SqList* L, ElemType* e)
{
    int p = LocataElem(*L, *e);
    if (p)
    {
        DeletePos(L, e, p);
        return SUC;
    }以上是关于数据结构--顺序表简单实现(总结)的主要内容,如果未能解决你的问题,请参考以下文章

课本总结:1:线性表

课本总结:1:线性表

课本总结:1:线性表

课本总结:1:线性表

[数据结构]——线性表总结(c语言代码实现)爆肝两万字!

Java数据结构:快速了解顺序表以及实现