线性表是最基本、最简单、也是最常用的一种数据结构。
线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储),但是把最后一个数据元素的尾指针指向了首位结点)。
我们说“线性”和“非线性”,只在逻辑层次上讨论,而不考虑存储层次,所以双向链表和循环链表依旧是线性表。
在数据结构逻辑层次上细分,线性表可分为一般线性表和受限线性表。一般线性表也就是我们通常所说的“线性表”,可以自由的删除或添加结点。受限线性表主要包括栈和队列,受限表示对结点的操作受限制。
线性表的逻辑结构简单,便于实现和操作。因此,线性表这种数据结构在实际应用中是广泛采用的一种数据结构。
/*
线性表:是指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 型,在实际应用中,可以根据需要修改相应的数据类型,可以是各种实体类对象