慕课网之C++数据结构学习笔记--线性表篇(一,顺序表)

线性表是最基本、最简单、也是最常用的一种数据结构。

线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储),但是把最后一个数据元素的尾指针指向了首位结点)。

我们说“线性”和“非线性”,只在逻辑层次上讨论,而不考虑存储层次,所以双向链表和循环链表依旧是线性表。

在数据结构逻辑层次上细分,线性表可分为一般线性表和受限线性表。一般线性表也就是我们通常所说的“线性表”,可以自由的删除或添加结点。受限线性表主要包括栈和队列,受限表示对结点的操作受限制。

线性表的逻辑结构简单,便于实现和操作。因此,线性表这种数据结构在实际应用中是广泛采用的一种数据结构。

/*
线性表:是指N个数据元素的有限序列
线性表大致分为两大类:顺序表(数组)和链表
而链表又分为:静态链表,单链表,循环链表,双向链表
顺序表在使用数组表达时优势在于访问速度快,搜索能力强
*/

关于线性表的概念就科普到这里,下面用代码讲解线性表中顺序表的实现:

首先定义一个List类,其中头文件是List.h

#ifndef LIST_H
#define LIST_H


class List
{
public:
    List(int size);//构造函数,初始化线性表
    ~List();//析构函数,销毁线性表
    void ClearList();//清空线性表
    bool ListEmpty();//判断线性表是否为空
    int ListLength();//获取线性表的长度
    bool GetElem(int i, int *e);//获取指定元素
    int LocateElem(int *e);//寻找第一个满足e的数据元素的位序
    bool PriorElem(int *currentElem, int *preElem);//获取指定元素的前驱
    bool NextElem(int *currentElem, int *nextElem);//获取指定元素的后继
    void ListTraverse();//遍历整个线性表
    bool ListInsert(int i, int *e);//在指定位置插入元素
    bool ListDelete(int i, int *e);//删除指定位置的元素

private:
    int *m_pList;
    int m_iSize;
    int m_iLength;
};
#endif // !LIST_H

下面是List.cpp文件

#include "List.h"
#include

using namespace std;

//构造函数,初始化线性表
List::List(int size)
{
    m_iSize = size;
    m_pList = new int[m_iSize];
    m_iLength = 0;

}
//析构函数,销毁线性表
List::~List()
{
    delete []m_pList;
    m_pList = NULL;
}
//清空线性表
void List::ClearList()
{
    m_iLength = 0;
}
//判断线性表是否为空
bool List::ListEmpty()
{
    if (m_iLength == 0)
    {
        return true;
    }
    return false;
}
//获取线性表的长度
int List::ListLength()
{
    return m_iLength;
}
//获取指定元素
bool List::GetElem(int i, int * e)
{
    if(i < 0 || i >= m_iSize)
    {
        return false;
    }
    *e = m_pList[i];
    return true;
}
//寻找第一个满足e的数据元素的位序
int List::LocateElem(int * e)
{
    for (int i = 0; i < m_iLength; i++)
    {
        if (m_pList[i] == *e)
        {
            return i;
        }
    }
    return -1;
}
//获取指定元素的前驱
bool List::PriorElem(int * currentElem, int * preElem)
{
    int temp = LocateElem(currentElem);
    if(temp == -1)
    {
        return false;
    }
    else
    {
        if (temp == 0)
        {
            return false;
        }
        else
        {
            *preElem = m_pList[temp - 1];
            return true;
        }
    }
}
//获取指定元素的后继
bool List::NextElem(int * currentElem, int * nextElem)
{
    
    int temp = LocateElem(currentElem);
    if (temp == -1)
    {
        return false;
    }
    else
    {
        if (temp == m_iLength - 1)
        {
            return false;
        }
        else
        {
            *nextElem = m_pList[temp + 1];
            return true;
        }
    }

}
//遍历整个线性表
void List::ListTraverse()
{
    for (int i = 0; i < m_iLength; i++)
    {
        cout << m_pList[i] << endl;
    }
}
//在指定位置插入元素
bool List::ListInsert(int i, int * e)
{
    if (i < 0 || i > m_iLength)
    {
        return false;
    }
    for (int k = m_iLength; k >= i; k--)
    {
        m_pList[k + 1] = m_pList[k];

    }
    m_pList[i] = *e;
    m_iLength++;
    return true;
}
//删除指定位置的元素
bool List::ListDelete(int i, int * e)
{
    if (i < 0 || i >= m_iLength)
    {
        return false;
    }
    *e = m_pList[i];
    for (int k = i + 1; k < m_iLength; k++)
    {
        m_pList[k - 1] = m_pList[k];
    }
    m_iLength--;
    return true;
}

下面是主函数,测试一下这个list:demo.cpp

#include "stdio.h"
#include "stdlib.h"
#include "List.h"
#include

using namespace std;
/***************************************************************************************/
/*
    线性表--顺序表

    3 5 7 2 9 1 8

    前驱  后继
    C语言类型的写法
    BOOL InitList(List **list);//创建线性表
    void DestroyList(List *list);//销毁线性表
    void ClearList(List *list);//清空线性表
    BOOL ListEmpty(List *list);//判断线性表是否为空
    int ListLength(List *list);//获取线性表长度
    BOOL GetElem(List *list, int i, Elem *e);//获取指定元素
    int LocateElem(List *list, Elem *e);//寻找第一个满足e的数据元素的位序
    BOOL PriorElem(List *list, Elem *currentElem, Elem *preElem);//获取指定元素的前驱
    BOOL NextElem(List *list, Elem *currentElem, Elem *preElem);//获取指定元素的后继
    BOOL ListInsert(List *list, int i, Elem *e);//在第i个位置插入元素
    BOOL ListDelete(List *list, int i, Elem *e);//删除第i个位置的元素
    void ListTraverse(List *list);//遍历线性表

*/
/***************************************************************************************/

int main()
{
    //3 5 7 2 9 1 8
    int e1 = 3;
    int e2 = 5;
    int e3 = 7;
    int e4 = 2;
    int e5 = 9;
    int e6 = 1;
    int e7 = 8;
    int temp = 0;
    List *list1 = new List(10);

    cout << "length:" << list1->ListLength() << endl;
    list1->ListInsert(0, &e1);
    cout << "length:" << list1->ListLength() << endl;
    list1->ListInsert(1, &e2);
    cout << "length:" << list1->ListLength() << endl;
    list1->ListInsert(2, &e3);
    list1->ListInsert(3, &e4);
    list1->ListInsert(4, &e5);
    list1->ListInsert(5, &e6);
    cout << "length:" << list1->ListLength() << endl;
    list1->ListInsert(6, &e7);

    list1->ListTraverse();

    list1->PriorElem(&e4, &temp);
    cout << "temp:" << temp << endl;
    list1->NextElem(&e4, &temp);
    cout << "temp:" << temp << endl;
    list1->GetElem(0, &temp);
    cout << "temp:" << temp << endl;

    list1->LocateElem(&temp);

    list1->ListDelete(0, &temp);

    if (!list1->ListEmpty())
    {
        cout << "not empty " << endl;
    }
    list1->ClearList();
    if (list1->ListEmpty())
    {
        cout << "empty " << endl;
    }
    list1->ListTraverse();

    cout << "#" << temp << endl;

    delete list1;
    return 0;
}

在这里我们选择顺序表中的数据类型是int 型,在实际应用中,可以根据需要修改相应的数据类型,可以是各种实体类对象

转载于:https://my.oschina.net/ykduan/blog/1498796

你可能感兴趣的:(慕课网之C++数据结构学习笔记--线性表篇(一,顺序表))