线性表--顺序存储结构

线性表的定义

线性表(亦作顺序表)是最基本、最简单、也是最常用的一种数据结构。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。线性表的逻辑结构简单,便于实现和操作。因此,线性表这种数据结构在实际应用中是广泛采用的一种数据结构。

线性表的抽象数据类型

ADT 线性表(List)

Data

线性表的数据对象集合为{a1,a2,……,an},每个元素的类型均为DataType。其中除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。
Operation

  • InitList(SqList *L); 构造一个空的线性表L
  • DestroyList(SqList *L); 销毁线性表Status ClearList(SqList *L);清空线性表
  • ListEmpty(SqList L); 判断线性表是否为空
  • LocateElem(SqList L, ElemType e, Status(*compare)(ElemType,ElemType)); 返回第一个与e满足compare关系的数据元素的位序
  • GetElem(SqList L, int i, ElemType *e);返回线性表总第i个数据元素的值
  • ListInsert(SqList *L, int i, ElemType e);在线性表第i个位置之前插入新的数据元素e
  • PriorElem(SqList L, ElemType cur_e, ElemType *pre_e); //返回指定元素的前驱
  • NextElem(SqList L, ElemType cur_e, ElemType *next_e); //返回指定元素的后继
  • ListDelete(SqList *L, int i, ElemType *e);删除线性表中指定的元素
  • ListTraverse(SqList L, void(vist)(ElemType ));遍历整个链表

线性表的顺序存储结构实现

  1. sqlist.h
/*
防止重复引用头文件
*/
#pragma once
#ifndef SQLIST_H
#define SQLIST_H

#define INIT_LIST_SIZE 10       //线性表存储空间的初始分配量
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define LISTINCREMENT 10    //线性表存储空间的分配增量

typedef int Status;     //返回的状态
typedef int ElemType;   //数据的类型

typedef struct SqList
{
    ElemType *data;     //线性表的基地址
    int length;     //线性表的当前长度
    int listsize;       //当前分配的存储空间
};

Status InitList(SqList *L);     //构造一个空的线性表L

Status DestroyList(SqList *L);      //销毁线性表

Status ClearList(SqList *L);        //清空线性表

Status ListEmpty(SqList L);     //判断线性表是否为空

Status LocateElem(SqList L, ElemType e, Status(*compare)(ElemType,ElemType));       //返回第一个与e满足compare关系的数据元素的位序

Status GetElem(SqList L, int i, ElemType *e);       //返回线性表总第i个数据元素的值

Status ListInsert(SqList *L, int i, ElemType e);        //在线性表第i个位置之前插入新的数据元素e

Status PriorElem(SqList L, ElemType cur_e, ElemType *pre_e);        //返回指定元素的前驱

Status NextElem(SqList L, ElemType cur_e, ElemType *next_e);        //返回指定元素的后继

Status ListDelete(SqList *L, int i, ElemType *e);       //删除线性表中指定的元素

Status ListTraverse(SqList L, void(*vist)(ElemType *));

void vist(ElemType *elem);

#endif
  1. sqlist.cpp
#include "sqlist.h"
#include <iostream>

using namespace std;

Status InitList(SqList *L)
{
    L->data = (ElemType*)malloc(INIT_LIST_SIZE*sizeof(ElemType));
    if (!L->data)
        return ERROR;
    L->length = 0;
    L->listsize = INIT_LIST_SIZE;
    return OK;
}

Status DestroyList(SqList *L)
{
    if (L->data)
        free(L->data);      //销毁线性表
    return OK;
}

Status ClearList(SqList *L)
{
    L->length = 0;  //将线性表置为空表
    return OK;
}

Status ListEmpty(SqList L)
{
    if (L.length == 0)      //长度为0时,线性表为空表
        return TRUE;
    return FALSE;
}

Status ListLength(SqList L)
{
    return L.length;        //线性表长度
}

Status LocateElem(SqList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
    int i = 1;
    ElemType *p = L.data;
    while (i < L.length && !(*compare)(e, *p++))
        ++i;
    if (i <= L.length)//返回满足关系compare的元素
        return i;
    else
        return FALSE;
}

Status GetElem(SqList L, int i, ElemType *e)
{
    if (L.length == 0 || i < 0 || i > L.length)     //要查找的i值不合法
        return ERROR;
    *e = L.data[i - 1];     //得到要查找的元素
    return OK;
}

Status ListInsert(SqList *L, int i, ElemType e)
{
    ElemType *newbase, *q , *p ;

    if (i<1 || i>L->length + 1)     //当前插入的位置不合法
        return ERROR;
    if (L->length > L->listsize)        //当前分配存储空间已满,增加分配
    {
        newbase = (ElemType*)realloc(L->data, LISTINCREMENT*sizeof(ElemType));
        if (!newbase)
            return ERROR;       //存储空间分配失败
        L->data = newbase;      //新基址
        L->listsize += LISTINCREMENT;
    }
    q = L->data + i - 1;        //插入的位置
    p = L->data + L->length - 1;
    for (p; p >= q; --p)
        *(p+1) = *p;        //插入位置之后的元素后移
    *q = e;     //插入元素
    ++L->length;        //线性表的长度增加1
    //cout << "ListInsert" << endl;
    return OK;

}

Status PriorElem(SqList L, ElemType cur_e, ElemType *pre_e)
{
    /* 初始条件:顺序线性表L已存在 */
    /* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
    /*           否则操作失败,pre_e无定义 */

    ElemType *p = L.data + 1;       //指向线性表第二个元素的指针
    int i = 2;      //循环开始
    while (i <= L.length && *p != cur_e)
    {
        i++;
        p++;
    }
    if (i > L.length)
        return ERROR;       //循环控制次数超出范围跳出循环
    else
    {
        *pre_e = *--p;      //找到与之匹配的元素跳出循环
        return OK;
    }
}

Status NextElem(SqList L, ElemType cur_e, ElemType *next_e)
{
    /* 初始条件:顺序线性表L已存在 */
    /* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
    /* 否则操作失败,next_e无定义 */

    int i = 1;
    ElemType *p = L.data;
    while (i < L.length && *p != cur_e)
    {
        i++;
        p++;
    }
    if (i >= L.length)
        return ERROR;
    else
    {
        *next_e = *++p;
        return OK;
    }
}

Status ListDelete(SqList *L, int i, ElemType *e)
{
    /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
    /* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
    ElemType *q, *p;
    if (i < 0 || i > L->length)     //i值不合法
        return ERROR;
    q= L->data + i -1;      //q为被删除元素的指针
    *e = *q;
    p = L->data + L->length -1;     //p为表位的指针
    for (++q ; q <= p; q++)
    {
        *(q-1) = *q;        //被删除后的元素前移
    }
    L->length --;       //表的长度减1
    return OK;
}

Status ListTraverse(SqList L, void(*vist)(ElemType *))
{
    int i = 0;
    ElemType *p = L.data;
    for (i; i < L.length; i++)
    {
        vist(p++);
    }
    return OK;
}
void vist(ElemType *elem)
{
    cout << *elem << " ";
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值