线性表之顺序表(一)

来源:互联网 发布:easycharts 数据小偷 编辑:程序博客网 时间:2024/06/10 18:45

在这里我们将介绍线性表的顺序存储结构–顺序表。这里我们介绍两种类型的顺序表,一种是静态的顺序表,另一种是动态增长的顺序表;并使用C和C++两种语言进行描述。这里给出C语言实现的具体的代码和说明,而C++的实现只是简单贴代码,不再详细说明。

一、相关概念

1.顺序表的概念
线性表的顺序存储结构称为顺序表(sequential list).
2.特点
(1)顺序表是用一段地址连续的存储单元一次存储线性表的数据元素;(2)相邻元素不仅逻辑上相邻,而且在物理内存上也是相邻的;(3)顺序表的元素可以随机存取(访问)(4)插入和删除比较麻烦,需要大量移动元素

二、静态顺序表

1.结构体定义(C语言描述)
顺序表和数组本质上一样的,只不过比数组多了一个记录有效元素个数的变量,其他特点基本都一样,比如说随机访问等。
#define SIZE 10 //静态顺序表最大的元素个数上限typedef struct Seqlist{    int iElem_a[SIZE]; //顺序表总空间    int iLength_st;//表中有效元素个数}Seqlist;
2.顺序表操作
我们将顺序表操作的函数的声明写在Seqlist.h文件中:
#ifndef SEQLIST_H_      //防止头文件被重复包含#define SEQLIST_H_#define SIZE 10typedef struct Sqlist{    int iElem_a[SIZE];    int iLength_st;}Sqlist;void InitSeqlist(Sqlist *pList);    //顺序表初始化bool Insert(Sqlist *pList, int iPos, int iVal);//插入bool DeleteByPos(Sqlist *pList, int iPos);//删除void Destroy(Sqlist *pList);//销毁顺序表,在静态顺序表中没实质性作用void Clear(Sqlist *pList);//清空顺序表bool IsEmpty(Sqlist *pList);//顺序表为空返回truebool IsFull(Sqlist *pList);//顺序表满返回trueint  GetLength(Sqlist *pList);//获取顺序表有效元素个数bool GetValByPos(Sqlist *pList, int iPos, int *iRetVal);//获取指定位置元素void PrintSqlist(Sqlist *pList);//输出顺序表#endif

下面在Seqlist.c文件中给出顺序表操作的具体实现:

#include <stdio.h>#include <stdlib.h>#include "Seqlist.h"int main(void){    Sqlist list;    InitSeqlist(&list);    for (int i = 0; i < 12; ++i)    {        Insert(&list, 0, i);    }    PrintSqlist(&list);    Insert(&list, 10, 10);    PrintSqlist(&list);    /*for (int i = 0; i < 12; ++i)    {        DeleteByPos(&list, 0);        PrintSqlist(&list);    }    PrintSqlist(&list);*/    for (int i = 0; i < 12; ++i)    {        int iRt;        GetValByPos(&list, i, &iRt);        printf("%5d\n", iRt);    }    printf("\n");    return 0;}//初始化顺序表,注意异常情况检查void InitSeqlist(Sqlist *pList){    if (NULL == pList)  //确保链表存在    {        printf("The Seqlist isn't exist!!!\n");        return;    }    pList->iLength_st = 0;}//插入元素,先判断是否顺序表已满,然后再判断插入位置是否正确,移动元素插入bool Insert(Sqlist *pList, int iPos, int iVal){    //顺序表存在而且没有满    if (pList == NULL)    {        printf("The Sqlist isn't exist!!!\n");         return false;    }    if (IsFull(pList))    {        printf("The Sqlist is full!\n");        return false;    }    //插入位置是否合法    if (iPos > pList->iLength_st || iPos < 0)    {        printf("The Insert positon is valid.\n");          return false;    }    //移动元素       for (int iIndex = pList->iLength_st - 1; iIndex >= iPos; --iIndex)    {        pList->iElem_a[iIndex + 1] = pList->iElem_a[iIndex];    }    //放入    pList->iElem_a[iPos] = iVal;    pList->iLength_st += 1;    return true;}//删除指定位置的元素,找到删除的元素的位置后,直接移动元素进行覆盖,记得改变顺序表有效元素的个数bool DeleteByPos(Sqlist *pList, int iPos){    if (NULL == pList)    {        printf("The seqlist isn't exist!!!\n");        return false;    }    if (IsEmpty(pList))    {        //printf("The seqlist is empty!!!\n");        return false;    }    if (iPos < 0 || iPos > pList->iLength_st - 1)    {        printf("The insert position is valid!!!\n");        return false;    }    for (int iIndex = iPos; iIndex < pList->iLength_st - 1; ++iIndex)    {        pList->iElem_a[iIndex] = pList->iElem_a[iIndex + 1];    }    --pList->iLength_st;    return true;}//销毁顺序表,因为这里是静态顺序表,所以这个函数没有实质性的作用void Destroy(Sqlist *pList){    Clear(pList);}//清空顺序表,直接将记录顺序表有效元素个数的变量置为0void Clear(Sqlist *pList){    if (NULL == pList)    {        printf("The seqlist isn't exist\n");        return;    }    pList->iLength_st = 0;}//判断顺序表是否为空bool IsEmpty(Sqlist *pList){    if (NULL == pList)    {        printf("The Seqlist isn't exist!!!\n");        return false;    }    return 0 == pList->iLength_st;}//判断顺序表是否已满bool IsFull(Sqlist *pList){    if (NULL == pList)    {        printf("The Seqlist isn't exist!!!\n");        return false;    }    return SIZE == pList->iLength_st;}//获取顺序表有效元素的个数int  GetLength(Sqlist *pList){    if (NULL == pList)    {        printf("The seqlist isn't exist.\n");        return -1;    }    return pList->iLength_st;}//获取顺序表中iPos位置元素的值bool GetValByPos(Sqlist *pList, int iPos, int *iRetVal){    if (NULL == pList)    {        printf("The seqlist isn't exist.\n");        return false;    }    if (iPos < 0 || iPos >= pList->iLength_st)    {        printf("The position is valid\n");        return false;    }    *iRetVal = pList->iElem_a[iPos];    return true;}//打印顺序表中的元素void PrintSqlist(Sqlist *pList){    if (NULL == pList || pList->iLength_st == 0)    {        return;    }    for (int iCount = 0; iCount < pList->iLength_st; ++iCount)    {        printf("%5d", pList->iElem_a[iCount]);    }    printf("\n");}

三、动态顺序表

动态顺序表和静态顺序表的区别在于动态顺序表可以动态进行增长,而静态顺序表的最大容量是在程序运行前已经写好的,无法改变。
1.结构体定义(C语言描述)
#define INIT_SIZE 10    //初始化顺序表大小#define INC_SIZE 10     //顺序表的分配增量typedef struct DSqlist{    int *iElem_st;  //存储空间基址    int iLength_st; //当前长度    int iSize_st;   //当前分配的存储容量}DSqlist;
2.动态顺序表操作
动态增长的顺序表和静态顺序表的操作大部分相同,主要不同在于两个地方。一个是当顺序表满时,动态顺序表可以再增长从而插入元素,而静态顺序表则无法再插入元素;二是在销毁顺序表时两者不一样。我们将顺序表操作的函数的声明写在DynamicSeqlist.h文件中:
#ifndef DYNAMICSEQLIST_H_#define DYNAMICSEQLIST_H_#define INIT_SIZE 10    //初始化顺序表大小#define INC_SIZE 10     //顺序表的分配增量typedef struct DSqlist{    int *iElem_st;  //存储空间基址    int iLength_st; //当前长度    int iSize_st;   //当前分配的存储容量}DSqlist;bool IsExist(DSqlist *pList);   //判断顺序表是否存在void InitDSeqlist(DSqlist *pList);  //初始化bool Insert(DSqlist *pList, int iPos, int iVal);//插入bool DeleteByPos(DSqlist *pList, int iPos); //删除void Destroy(DSqlist *pList);   //销毁void Clear(DSqlist *pList);     //清空bool IsEmpty(DSqlist *pList);   //判断是否为空bool IsFull(DSqlist *pList);    //判断是否为满int  GetLength(DSqlist *pList); //获取有效元素个数bool GetValByPos(DSqlist *pList, int iPos, int *iRetVal); //获取指定位置元素的值void PrintSqlist(DSqlist *pList); //打印元素bool Resize(DSqlist *pList);    //重新分配内存空间#endif
下面在DynamicSeqlist.c文件中给出在以上操作的具体C语言代码实现:
#include"DynamicSeqlist.h"#include <stdio.h>#include <stdlib.h>#include <string.h>int main(void){    DSqlist list;    InitDSeqlist(&list);    for (int i = 0; i < 15; ++i)    {        Insert(&list, 0, i);    }    PrintSqlist(&list);    printf("%5d\n", list.iSize_st);    for (int i = 0; i < 15; ++i)    {        DeleteByPos(&list, 0);        PrintSqlist(&list);    }    PrintSqlist(&list);    return 0;}bool IsExist(DSqlist *pList){    return pList != NULL;}void InitDSeqlist(DSqlist *pList){    if (!IsExist(pList))    {        printf("The dynamic seqlist isn't exist.\n");        return;    }    pList->iElem_st = (int*)malloc(sizeof(int) * INIT_SIZE);    if (NULL == pList->iElem_st)    {        printf("Alloc the memory is failed.\n");        return;    }    pList->iSize_st = INIT_SIZE;    pList->iLength_st = 0;}bool Insert(DSqlist *pList, int iPos, int iVal){    if (!IsExist(pList))    {        printf("The dynamic seqlist isn't exist.\n");        return false;    }    if (IsFull(pList))    {        Resize(pList);    }    if (iPos < 0 || iPos > pList->iLength_st)    {        printf("The insert position is valid.\n");        return false;    }    for (int iIndex = pList->iLength_st - 1; iIndex >= iPos; --iIndex)    {        pList->iElem_st[iIndex + 1] = pList->iElem_st[iIndex];    }    pList->iElem_st[iPos] = iVal;       pList->iLength_st++;    return true;}bool DeleteByPos(DSqlist *pList, int iPos){    if (!IsExist(pList))    {        printf("The dynamic seqlist isn't exist.\n");        return false;    }    if (IsEmpty(pList))    {        printf("The seqlist is empty.\n");        return false;    }    if (iPos < 0 || iPos >= pList->iLength_st)    {        printf("The delete position is valid.\n");        return false;    }    for (int iIndex = iPos; iIndex < pList->iLength_st - 1; ++iIndex)    {        pList->iElem_st[iIndex] = pList->iElem_st[iIndex + 1];    }    pList->iLength_st--;    return true;}void Destroy(DSqlist *pList){    if (!IsExist(pList))    {        printf("The dynamic seqlist isn't exist.\n");        return;    }    free(pList->iElem_st);    pList->iLength_st = 0;    pList->iSize_st = 0;    pList->iElem_st = NULL;}void Clear(DSqlist *pList){    if (!IsExist(pList))    {        printf("The dynamic seqlist isn't exist.\n");        return;    }    pList->iLength_st = 0;}bool IsEmpty(DSqlist *pList){    if (!IsExist(pList))    {        printf("The dynamic seqlist isn't exist.\n");        return false;    }    return (pList->iLength_st == 0);}bool IsFull(DSqlist *pList){    if (!IsExist(pList))    {        printf("The dynamic seqlist isn't exist.\n");        return false;    }    return (pList->iLength_st == pList->iSize_st);}int  GetLength(DSqlist *pList){    if (!IsExist(pList))    {        printf("The dynamic seqlist isn't exist.\n");        return -1;    }    return pList->iLength_st;}bool GetValByPos(DSqlist *pList, int iPos, int *iRetVal){    if (!IsExist(pList))    {        printf("The dynamic seqlist isn't exist.\n");        return false;    }    if (iPos < 0 || iPos >= pList->iLength_st)    {        printf("The posiont is valid.\n");        return false;    }    *iRetVal = pList->iElem_st[iPos];    return true;}void PrintSqlist(DSqlist *pList){    if (!IsExist(pList))    {        printf("The dynamic seqlist isn't exist.\n");        return;    }    for (int iIndex = 0; iIndex < pList->iLength_st; ++iIndex)    {        printf("%5d", pList->iElem_st[iIndex]);    }    printf("\n");}bool  Resize(DSqlist *pList){    if (!IsExist(pList))    {        printf("The dynamic seqlist isn't exist.\n");        return false;    }    int *pTemp = pList->iElem_st;    pList->iElem_st = (int*)malloc(sizeof(int)*(pList->iSize_st + INC_SIZE));       if (NULL != pList->iElem_st)    {        memcpy(pList->iElem_st, pTemp, sizeof(int) * pList->iSize_st);        pList->iSize_st += INC_SIZE;        free(pTemp);        pTemp = NULL;        return true;    }    else    {        return false;    }}

下面直接给出使用C++实现顺序表的代码:
//CppSeqlist.h头文件

#pragma onceconst int SIZE = 10;class CSeqList{public:    CSeqList();    ~CSeqList();    int Length();    bool Get(int i, int &iRtVal);    int Locate(int x);    void Insert(int i, int x);    void Detele(int i);    void PrintList();private:    int _iData_a[SIZE];     //存放数据元素的数组    int _iLength;           //线性表的长度};//CppSeqlist.cpp#include "CppSeqlist.h"#include <iostream>using namespace std;CSeqList::CSeqList(){    _iLength = 0;}CSeqList::~CSeqList(){}int CSeqList::Length(){    return _iLength;}bool CSeqList::Get(int i, int &iRtVal){    if (i < 0 || i > _iLength - 1)    {        cout << "the position is valid.\n" << endl;        return false;    }    iRtVal = _iData_a[i];    return true;}void CSeqList::Insert(int i, int x){    if (_iLength == SIZE)    {        cout << "The seqlist is full." << endl;        return;    }    if (i < 0 || i > _iLength)    {        cout << "the position is valid." << endl;        return;    }    for (int iIndex = _iLength - 1; iIndex >= i; --iIndex)    {        _iData_a[iIndex + 1] = _iData_a[iIndex];    }    _iData_a[i] = x;    ++_iLength;}void CSeqList::Detele(int i){    if (i < 0 || i > _iLength - 1)    {        cout << "The position is valid." << endl;        return;    }    for (int iIndex = i; iIndex < _iLength - 1; ++iIndex)    {        _iData_a[iIndex] = _iData_a[iIndex + 1];    }    --_iLength;}void CSeqList::PrintList(){    for (int iIndex = 0; iIndex < _iLength; ++iIndex)    {        cout << _iData_a[iIndex] << "   ";    }    cout << endl;}int main(void){    CSeqList list;    for (int i = 0; i < 12; ++i)    {        list.Insert(0, i);    }    list.PrintList();    return 0;}
原创粉丝点击