c/c++常用算法(1) -- 数据结构(线性表的顺序存储)

一、线性表描述


      线性结构是最常用、最简单的一种数据结构。而线性表是一种典型的线性结构。其基本特点是线性表中的数据元素是有序且是有限的。

在这种结构中:

            ①存在一个唯一的被称为“第一个”的数据元素;

            ②存在一个唯一的被称为“最后一个”的数据元素;

            ③除第一个元素外,每个元素均有唯一一个直接前驱;

            ④除最后一个元素外,每个元素均有唯一一个直接后继。


二、线性表定义


      线性表(Linear List):是由n(n≧0)个数据元素(结点)a1,a2,…an组成的有限序列。该序列中的所有结点具有相同的数据类型。其中数据元素的个数n称为线性表的长度。

      当n=0时,称为空表。

      当n>0时,将非空的线性表记作: (a1,a2,…an)        

      a1称为线性表的第一个(首)结点,an称为线性表的最后一个(尾)结点。

      a1,a2,…ai-1都是ai(2≦i≦n)的前驱,其中ai-1是ai的直接前驱;

      ai+1,ai+2,…an都是ai(1≦i≦n-1)的后继,其中ai+1是ai的直接后继。


三、线性表的逻辑结构


      线性表中的数据元素ai所代表的具体含义随具体应用的不同而不同,在线性表的定义中,只不过是一个抽象的表示符号。

      ◆  线性表中的结点可以是单值元素(每个元素只有一个数据项)。


      例1: 26个英文字母组成的字母表:(A,B,C、…、Z)

      例2 :某校从1978年到1983年各种型号的计算机拥有量的变化情况:(6,17,28,50,92,188)

      例3 :一副扑克的点数    (2,3,4,…,J,Q,K,A)


      ◆  线性表中的结点可以是记录型元素,每个元素含有多个数据项,每个项称为结点的一个域 。每个元素有一个可以唯一标识每个结点的数据项组,称为关键字。


      例4 :某校2001级同学的基本情况:{(‘2001414101’,‘张里户’,‘男’,06/24/1983), (‘2001414102’,‘张化司’,‘男’,08/12/1984)…, (‘2001414102’,‘李利辣’,‘女’,08/12/1984)}


      ◆若线性表中的结点是按值(或按关键字值)由小到大(或由大到小)排列的,称线性表是有序的。

      ◆线性表是一种相当灵活的数据结构,其长度可根据需要增长或缩短。

      ◆对线性表的数据元素可以访问、插入和删除。


四、线性表的抽象数据类型定义

ADT List{
    数据对象:D = { ai | ai∈ElemSet,  i=1,2,…,n, n≧0 }
    数据关系:R = {<ai-1, ai> | ai-1, ai∈D,  i=2,3,…,n }
    基本操作:
    InitList( &L )
    操作结果:构造一个空的线性表L;
    ListLength( L )
    初始条件:线性表L已存在;
    操作结果:若L为空表,则返回TRUE,否则返回FALSE;
    ….
    GetElem( L, i, &e )
    初始条件:线性表L已存在,1≦i≦ListLength(L);
    操作结果:用e返回L中第i个数据元素的值;
    ListInsert ( L, i, &e )
    初始条件:线性表L已存在,1≦i≦ListLength(L) ;
    操作结果:在线性表L中的第i个位置插入元素e;
    …
    } ADT List


五、线性表的顺序存储结构


      顺序存储:把线性表的结点按逻辑顺序依次存放在一组地址连续的存储单元里。用这种方法存储的线性表简称顺序表。

      顺序存储的线性表的特点:

             ◆ 线性表的逻辑顺序与物理顺序一致;

             ◆ 数据元素之间的关系是以元素在计算机内“物理位置相邻”来体现。

      设有非空的线性表:(a1,a2,…an)。顺序存储如图2-1所示。




六、实现代码(顺序表操作示例):


sequenceList.h

#ifndef __CHelloWorld__sequenceList__
#define __CHelloWorld__sequenceList__

#include <iostream>
#include <string.h>

#define MAXLEN 100  //定义顺序表的最大长度

typedef struct
{
    char key[10];   //结点的关键字
    char name[20];
    int age;
}DATA;              //结点类型

typedef struct
{
    DATA ListData[MAXLEN + 1];  //保存顺序表的结构数组
    int ListLen;                //顺序表已存结点的数量
}SLType;


class SequenceList
{
public:
    void SLInit(SLType* SL);                    //初始化
    int SLLength(SLType* SL);                   //返回顺序表的元素数量
    int SLInsert(SLType* SL,int n,DATA data);   //插入数据
    int SLAdd(SLType* SL,DATA data);            //增加数据
    int SLDelete(SLType* SL,int n);             //删除数据
    DATA *SLFindByNum(SLType *SL,int n);        //按序号查询数据
    int SLFindByCout(SLType *SL,char *key);     //按key查询数据
    int SLAll(SLType *SL);                      //遍历结点
};

#endif /* defined(__CHelloWorld__sequenceList__) */
sequenceList.cpp

#include "sequenceList.h"
using namespace std;

void SequenceList::SLInit(SLType *SL)
{
    SL->ListLen = 0;
}

int SequenceList::SLLength(SLType *SL)
{
    return (SL->ListLen);
}

int SequenceList::SLInsert(SLType *SL, int n, DATA data)
{
    int i;
    if(SL->ListLen >= MAXLEN)
    {
        cout<<"顺序表已满,不能插入结点!"<<endl;
        return 0;
    }
    if (n<1 || n>SL->ListLen - 1)
    {
        cout<<"插入元素序号错误,不能插入元素!"<<endl;
        return 0;
    }
    
    for (i = SL->ListLen; i >= n; i--)
    {
        SL->ListData[i+1] = SL->ListData[i];
    }
    SL->ListData[n] = data;
    SL->ListLen++;
    return 1;
}

int SequenceList::SLAdd(SLType *SL, DATA data)
{
    if (SL->ListLen >= MAXLEN)
    {
        cout<<"顺序表已满,不能再添加结点!"<<endl;
        return 0;
    }
    SL->ListData[++SL->ListLen] = data;
	return 1;
}

int SequenceList::SLDelete(SLType *SL, int n)
{
    int i;
    if (n<1 || n>SL->ListLen+1)
    {
        cout<<"删除结点序号错误,不能删除结点!"<<endl;
        return 0;
    }
    
    for (i = n; i < SL->ListLen; i++)
    {
        SL->ListData[i] = SL->ListData[i+1];
    }
    SL->ListLen--;
    return 1;
}

DATA *SequenceList::SLFindByNum(SLType *SL, int n)
{
    if (n<1 || n>SL->ListLen+1)
    {
        cout<<"结点序号错误,不能返回结点!"<<endl;
        return NULL;
    }
    return &(SL->ListData[n]);
}


int SequenceList::SLFindByCout(SLType *SL, char *key)
{
    int i;
    for (i = 1; i<= SL->ListLen;i++)
    {
        if (strcmp(SL->ListData[i].key, key))
        {
            return i;
        }
    }
    return 0;
}

int SequenceList::SLAll(SLType *SL)
{
    int i;
    for (i = 1; i<=SL->ListLen; i++)
    {
        printf("(%s,%s,%d)\n",SL->ListData[i].key,SL->ListData[i].name,SL->ListData[i].age);
    }
    return 0;
}
main.cpp

#include "sequenceList.h"
using namespace std;

int main(int argc, const char * argv[])
{

    int i;
    SLType SL;
    DATA data;
    DATA *pdata;
    char key[10];
    std::cout << "顺序表操作演示\n";
    SequenceList *myList = new SequenceList();
    myList->SLInit(&SL);
    std::cout << "初始化完成\n";
    
    do
    {
        std::cout << "输入添加的结点(学号 姓名 年龄):";
        fflush(stdin);  //清空输入缓冲区
        scanf("%s%s%d",&data.key,&data.name,&data.age);
        
        if (data.age)   //年龄不能为0
        {
            if (!myList->SLAdd(&SL, data))
            {
                break;
            }
        }
        else
        {
            break;
        }
    } while (1);
    std::cout << "\n顺序表中的结点顺序为:\n";
    myList->SLAll(&SL);
    
    fflush(stdin);
    std::cout << "\n要取出结点的序号:\n";
    scanf("%d",&i);
    pdata = myList->SLFindByNum(&SL, i);
    if (pdata)
    {
         printf("第%d个结点为:(%s,%s,%d)\n",i,pdata->key,pdata->name,pdata->age);
        
    }
    delete myList;
    
    // insert code here...
    std::cout << "Hello, World!\n";
    return 0;
}

运行结果:

                        


参考书籍:《C/C++常用算法手册》  《数据结构-清华大学严蔚敏》


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热血枫叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值