所谓顺序表,即线性表的顺序存储结构。下面给出的是数据结构---线性表的定义。

ADT List{

  数据对象:

    线性表的数据对象的集合为{a1,a2,a3,...,an},每个元素的类型为ElemType。

  数据关系:

    除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每个元素有且仅有一个直接后继元素。

    数据元素之间的关系是一对一的关系。

  基础操作:

    InitList(&L);  //构造一个空的线性表

    DestroyList(&L); //销毁线性表

    ClearList(&L); //清空线性表

    ListEmpty(L); //若线性表为空,返回true,否则返回false

    ListLength(L);//求表长

    GetElem(L, i, &e); //将线性表中第i个元素赋值给e

    LocateElem(L, e, cmp()); //返回L中第一个满足cmp()函数的元素的序号,若不存在,则返回0

    ListInsert(&L, i, e); //在L中的第i个位置之前插入元素e且L的长度+1

    ListDelete(&L, i, &e); //删除L中的第i个元素并用e返回其值,且L的长度-1

    ListTraverse(L, visit()); //线性表的遍历,依次对每个元素调用visit函数

  其他操作:

    PrioElem(L, cur_e, &pre_e); //cue_e是L中的数据元素,用pre_e返回其前驱;若无前驱则操作失败

    NextElem(L, cue_e, &next_e); //cur_e是L中的数据元素,用next_e返回后继;若无后继则操作失败

    union(&L1, &L2); //求二者元素并集;又可根据线性表是否有序有不同的操作。

}

以下是线性表的顺序存储结构的多种实现方式,详细参阅代码。(大部分只实现了基础操作)

1.用C语言实现顺序表 静态数组方式

/************************************************************************
用C语言实现顺序表 静态数组方式
************************************************************************/
#include <cstdio> typedef int ElemType;
typedef int Status; const int ERROR = ;
const int OK = ;
const int TRUE = ;
const int FALSE = ;
const int LIST_SIZE = ; //定义顺序表结构ADT
typedef struct{
int elem[LIST_SIZE];
int length;
}SqList, *pList; //初始化顺序表
Status InitList(pList List)
{
List->length = ;
return OK;
} //释放顺序表
Status DestroyList(pList List)
{
List->length = ;
return OK;
} //判断顺序表是否为空 是 返回 1 否则 返回 0
Status ListEmpty(pList List)
{
if (List->length)
return FALSE;
return TRUE;
} //返回顺序表的长度
int ListLength(pList List)
{
return List->length;
} //根据下标获取元素
Status GetElem(pList List, int i, ElemType *e)
{
if (i < || i > List->length)
return ERROR;
//第i个数据元素存储在下标为i-1的数组中
*e = List->elem[i - ];
return OK;
} //判断给定数据是否为顺序表的元素
Status LocateElem(pList List, int e)
{
if (ListEmpty(List))
return ERROR;
for (int i = ; i < List->length; ++i)
{
if (e == List->elem[i])
return TRUE;
}
return FALSE;
} //返回元素的前驱
Status PriorElem(pList List, ElemType cur_e, ElemType *pre_e)
{
if ( == List->length)
return ERROR;
for (int i = ; i < List->length; ++i)
{
if (cur_e == List->elem[i] && i != ){
*pre_e = List->elem[i - ];
return OK;
}
}
return ERROR; } //返回元素cur_e的后驱
Status NextElem(pList List, ElemType cur_e, ElemType *next_e)
{
if ( == List->length)
return ERROR;
for (int i = ; i < List->length - ; ++i)
{
if (cur_e == List->elem[i]){
*next_e = List->elem[i + ];
return OK;
}
}
return ERROR;
} //在数据元素i之前插入新元素
Status ListInsert(pList List, int i, ElemType e)
{
if (i < || i > List->length + )
return ERROR;
if (LIST_SIZE <= List->length)
return ERROR;
//q为插入位置,次位置及之后的要先移位才能在q这插入
ElemType* q = &List->elem[i - ];
//移位
for (ElemType *p = &List->elem[List->length - ]; p >= q; --p)
*(p + ) = *p;
*q = e;
++List->length;
return OK;
} //删除顺序表中的第i个数据元素,并用e返回
Status ListDelete(pList List, int i, ElemType *e)
{
if (i < || i > List->length)
return ERROR;
//p为需要删除的元素地址 讲后面的一层层移位就好 q为最后一位元素地址
ElemType *p = &List->elem[i - ];
ElemType *q = &List->elem[List->length - ];
*e = *p;
//移位
while (p < q){
*p = *(p + );
++p;
}
--List->length;
return OK;
} //线性表的遍历
Status ListTraverse(pList List, void(*visit)(ElemType elem))
{
if (ListEmpty(List))
return ERROR;
for (int i = ; i < List->length; ++i)
visit(List->elem[i]);
return OK;
} void visit(ElemType e){
printf("%4d", e);
} int main()
{
#ifdef _LOCAL
freopen("input.txt", "r", stdin);
#endif
SqList MyList;
pList List = &MyList; InitList(List);
ElemType tmp;
for (int i = ; i <= ; ++i)
{
scanf("%d", &tmp);
if (!ListInsert(List, i, tmp)){
printf("ListInsert Error!\n");
}
} //if (!ListDelete(List, 5, &tmp)){
// printf("ListDelete Error!\n");
//}
//else{
// printf("Delete %d\n", tmp);
//} ListTraverse(List, visit); printf("\n"); return ;
}

2.C语言实现顺序表,内存动态分配方式

/************************************************************************
C语言实现顺序表,内存动态分配方式
************************************************************************/
#include <stdio.h>
#include <stdlib.h> #define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define LIST_INIT_SIZE 15
#define ADD_SIZE 10
#define OVERFLOW -2 typedef int ElemType;
typedef int Status; typedef struct{
int *elem;
int length; //线性表当前长度
int listsize; //顺序表已分配空间
}SqList, *pList; //创建一个顺序表
Status InitList(pList List){
List->elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
if (!List->elem)
exit(OVERFLOW);
List->length = ;
List->listsize = LIST_INIT_SIZE;
return OK;
} //销毁该顺序表
Status DestroyList(pList List){
if (List->elem){
free(List->elem);
List->elem = NULL;
return OK;
}
else{
return ERROR;
}
} //判断顺序表是否为空
Status ListEmpty(pList List){
if (List){
return !List->length;
}
return ERROR;
} //清空顺序表
Status ClearList(pList List){
if (List){
List->length = ;
return OK;
}
else{
return ERROR;
}
} //返回顺序表元素个数
Status ListLength(pList List){
if (List){
return List->length;
}
else{
return ERROR;
}
} //获取元素i
Status GetElem(pList List, int i, ElemType *e){
if (List){
if (i < || i > List->length)
return ERROR;
*e = List->elem[i - ];
return OK;
}
else{
return ERROR;
}
} //返回元素e的下标
Status LocateElem(pList List, ElemType e){
if (List){
for (int i = ; i < List->length; ++i)
{
if (e == List->elem[i])
return i + ;
}
return ;
}
else{
return ERROR;
}
} //i之前插入元素
Status ListInsert(pList List, int i, ElemType e){
if (List){
//插入位置出错,报错
if (i < || i > List->length + ){
return ERROR;
}
//空间已满,重新分配
if (List->length >= List->listsize){
//重新分配空间
ElemType *newbase = (ElemType*)realloc(List->elem, (List->listsize + ADD_SIZE)*sizeof(ElemType));
printf("Realloc!\n");
if (!newbase){
exit(OVERFLOW);
}
//将重新分配的空间赋给线性表中的指针
List->elem = newbase;
//更新当前已分配的空间
List->listsize += ADD_SIZE;
}
//利用指针p、q移位,p指向尾元素的后一位,q指向目标地址
ElemType *p = &List->elem[List->length];
ElemType *q = &List->elem[i - ];
while (p > q){
*p = *(p - );
--p;
}
*q = e;
++List->length;
return OK;
}
else
{
return ERROR;
}
} //删除i处元素
Status ListDelete(pList List, int i, ElemType *e){
if (List){
if (i < || i > List->length){
return ERROR;
}
ElemType *p = &List->elem[i - ];
ElemType *q = &List->elem[List->length-];
while (p < q){
*p = *(p + );
++p;
}
--List->length;
return OK;
}
else{
return ERROR;
}
} Status ListPrint(pList List)
{
if (List){
for (int i = ; i < List->length; ++i)
printf(i ? " %d" : "%d", List->elem[i]);
return OK;
}
else{
printf("Empty List!");
return ERROR;
}
} int main()
{
SqList MyList;
pList pMyList = &MyList;
InitList(pMyList);
for (int i = ; i <= ; ++i)
ListInsert(pMyList, i, i); ListPrint(pMyList); return ;
}

3.用C++实现顺序表 静态数组方式 面向对象

/************************************************************************
用C++实现顺序表 静态数组方式 面向对象
************************************************************************/
#include <cstdio> const bool OK = ;
const bool ERROR = ;
const bool TRUE = ;
const bool FALSE = ;
const int LIST_SIZE = ; typedef int ElemType;
typedef int Status; class SqList{
private:
ElemType elem[LIST_SIZE];
int length;
public:
SqList(); //默认构造函数
~SqList(); //析构函数
Status ListEmpty(); //判断顺序表是否为空
int ListLength(); //获取顺序表的长度
Status GetElem(int i, ElemType& e); //获取第i个元素
Status LocateElem(int e); //e为顺序表中的元素,返回e的下标,0表示失败
Status ListInsert(int i, ElemType e); //在第i个元素之前插入e并是length加1
Status ListDelete(int i, ElemType &e); //删除顺序表的第i个元素
Status ListTraverse(void (*visit)(ElemType &e)); //输出该顺序表
}; void visit(ElemType& e){
printf("%4d", e);
} int main()
{
SqList Test;
ElemType tmp; for (int i = ; i <= ; ++i)
Test.ListInsert(i, i);
//Test.ListDelete(3, tmp); Test.ListTraverse(visit);
putchar(); return ;
} SqList::SqList(){
this->length = ;
} SqList::~SqList(){
this->length = ;
} Status SqList::ListEmpty(){
return !length;
} int SqList::ListLength(){
return this->length;
} Status SqList::GetElem(int i, int& e){
if (i < || i > length)
return ERROR;
e = elem[i - ];
return OK;
} Status SqList::LocateElem(int e){
for (int i = ; i < length; ++i)
{
if (e == this->elem[i])
return i + ;
}
return ERROR;
} Status SqList::ListInsert(int i, int e){
if (i < || i > this->length + )
return ERROR;
if (this->length >= LIST_SIZE)
return ERROR;
//先将i位置及之后的元素后移,推荐使用指针实现
ElemType *q = &this->elem[i - ]; //q为目标地址
for (ElemType *p = &this->elem[this->length]; p > q; --p)
{
*p = *(p - );
}
*q = e;
++length;
return OK; } Status SqList::ListDelete(int i, int &e){
if (i < || i > length)
return ERROR;
//从目标地址的后一个元素开始一个个往前移
ElemType *p = &elem[i - ]; //p为目标地址
ElemType *q = &elem[length];//q为尾元素的地址
while (p < q){
*p = *(p + );
++p;
}
--length;
return OK;
} Status SqList::ListTraverse(void(*visit)(ElemType &e)){
if (length){
for (int i = ; i < length; ++i)
visit(elem[i]);
return OK;
}
else{
printf("Empty List!");
return OK;
} }

4.用C++和模板实现顺序表

/************************************************************************
用C++和模板实现顺序表
************************************************************************/
#include <cstdio> const int MAX_SIZE = ;
#define OK 1
#define ERROR 0
#define TRUE 1
//#define FALSE 0
#define OVERFLOW -1
typedef int Status; template<typename ElemType>
class SqList{
ElemType m_data[MAX_SIZE+]; //为了排序查找方便,从1下标开始存储
int m_length;
public:
//默认构造函数,相当于InitList()
SqList() :m_length(){}
//析构函数,相当于DestroyList(),但什么也不做
~SqList(){ }
//清空顺序表
void ClearList(){
m_length = ;
}
//判断线性表是否为空
bool ListEmpty(){
return !m_length;
}
//求表长
int ListLength(){
return m_length;
}
//取得顺序表中的第i个元素
Status GetElem(int i, ElemType& e){
if (i < || i > m_length)
return ERROR;
e = m_data[i];
return OK;
}
//返回L中第一个满足cmp()函数的元素的序号,若不存在,则返回0
Status LocateElem(ElemType e, bool(*cmp)(ElemType, ElemType)){
m_data[] = e;
int i = m_length;
while (!cmp(e, m_data[i])){
--i;
}
return i;
}
//在L中的第i个位置之前插入元素e且L的长度+1
Status ListInsert(int i, ElemType e){
if (i < || i > m_length + || m_length >= MAX_SIZE){
return ERROR;
}
for (int k = m_length; k >= i; --k){
m_data[k+] = m_data[k];
}
m_data[i] = e;
++m_length;
return OK;
}
//删除L中的第i个元素并用e返回其值,且L的长度-1
Status ListDelete(int i, ElemType& e){
if (i < || i > m_length)
return ERROR;
for (int j = i; j < m_length; ++j){
m_data[j] = m_data[j + ];
}
--m_length;
return OK;
}
//线性表的遍历,依次对每个元素调用visit函数
Status ListTraverse(void(*visit)(ElemType e)){
if (m_length == ){
printf("Empty SqList");
return ERROR;
}
for (int i = ; i <= m_length; ++i){
visit(m_data[i]);
}
return OK;
}
}; bool cmp(int a, int b){
return a == b;
} void visit(int a){
printf("%3d", a);
} int main()
{
#ifdef _LOCAL
freopen("input.txt", "r", stdin);
#endif
SqList<int> L;
int n, tmp;
scanf("%d", &n);
for (int i = ; i <= n; ++i){
scanf("%d", &tmp);
L.ListInsert(i, tmp);
}
L.ListDelete(, tmp); L.ListTraverse(visit); printf("\n"); }

顺序表及其多种实现方式 --- C/C++的更多相关文章

  1. 老郭带你学数据结构(C语言系列)2-线性表之动态顺序表

    一.基本概念: 线性表:由n个类型相同的数据元素组成的有限序列,记为(a1,a2,--an). 线性表的特征:其中的元素存在这序偶关系,元素之间存在着严格的次序关系. 顺序存储表:线性表中的元素依次存 ...

  2. 数据结构之动态顺序表(C实现)

    线性表有2种,分为顺序表和链表. 顺序表: 采用顺序存储方式,在一组地址连续的存储空间上存储数据元素的线性表(长度固定) 链表: 有3种,单链表.双向链表.循环链表(长度不固定) seqList.h ...

  3. K:顺序表和链表的比较

     顺序表和链表是线性表的两种基本实现形式(链表还有多种变化形式),对于这两种实现方式,没有一种方法可以称是最好的,他们各自有着各自的特点和优缺点,适用于不同的应用场景.  与顺序表相比,链表较为灵活, ...

  4. 数据结构4:顺序表(线性表的顺序存储结构)及C语言实现

    逻辑结构上呈线性分布的数据元素在实际的物理存储结构中也同样相互之间紧挨着,这种存储结构称为线性表的顺序存储结构. 也就是说,逻辑上具有线性关系的数据按照前后的次序全部存储在一整块连续的内存空间中,之间 ...

  5. 顺序表添加与删除元素以及 php实现顺序表实例

    对顺序表的操作,添加与删除元素. 增加元素 如下图所示  对顺序列表 Li [1328,693,2529,254]  添加一个元素 111 ,有三种方式: a)尾部端插入元素,时间复杂度O(1);  ...

  6. C语言实现顺序表(顺序存储结构)

    顺序表(顺序存储结构)及初始化过程详解 顺序表,全名顺序存储结构,是线性表的一种.通过<线性表>一节的学习我们知道,线性表用于存储逻辑关系为"一对一"的数据,顺序表自然 ...

  7. 数据结构:顺序表(python版)

    顺序表python版的实现(部分功能未实现) #!/usr/bin/env python # -*- coding:utf-8 -*- class SeqList(object): def __ini ...

  8. 数据结构顺序表删除所有特定元素x

    顺序表类定义: template<class T> class SeqList : { public: SeqList(int mSize); ~SeqList() { delete[] ...

  9. C#线性表之顺序表

    线性表是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract), 线性结构的特点是结构中的数据元素之间存在一对一的线性关系. 这种一对一的关系指的是数据元素之间的位置关系,即: ...

随机推荐

  1. POJ 3384

    题目大意: 给定一个多边形,给定一个圆的半径,要求在多边形中放置两个同样半径的圆,可相互覆盖,但不能超出多边形的范围,希望两个圆的面积覆盖和最大 输出任意一组满足的圆的圆心点 如果两个圆不相互覆盖,那 ...

  2. 租房时代,K2 BPM软件带你拥抱更好生活

    提到租房子,你的第一反应肯定就是心酸的找房路,奇葩的极品房东……但租房对于年轻人来说又是生存路上必须面对的挑战.现在有一家公司想给你一段租房时代的美好回忆,它就是优客逸家. 优客逸家,隶属于四川优客投 ...

  3. redis2.8--内存管理

    总而言之,redis内存管理是采用主要由操作系统自主控制内存分配,辅之以简单封装,达到简单且稍微改良的性能. 内存块,标记上本块size 如上图所示, 当调用zmalloc/zmalloc时,输入参数 ...

  4. sql 给数据库表 字段 添加注释

    最近发现一些代码生成器 有针对注释做一个很好的转化,之前建表的时候 没有这块的注释.现在想增加,专门去看了下 如何增加注释 1 -- 表加注释 2 EXEC sys.sp_addextendedpro ...

  5. 管理Fragment

    转载原地址:http://blog.csdn.net/harvic880925/article/details/44927375 相关文章: 1.<Fragment详解之一——概述>2.& ...

  6. php 封装分页查询类

    <?php /** file: page.class.php 完美分页类 Page */ class Page { private $total; //数据表中总记录数 private $lis ...

  7. php大力力 [023节]CREATE TABLE创建新表sql写字段备注(2015-08-27)

    2015-08-27 php大力力023.CREATE TABLE创建新表sql写字段备注 http://www.cnblogs.com/dalitongxue/p/4762182.html 参考: ...

  8. IOS源码封装成.bundle和.a文件,以及加入xib的具体方法,翻遍网络,仅此一家完美翻译!! IOS7!!(3) 完美结局

    以上翻译有误解之处,现在简单做法如下: 经过深入研究,才感觉明白了内部机制,现在简单介绍于下,主要步骤:xcode5 创建库项目,删掉测试文件和默认创建的类,添加viewController类带xib ...

  9. array_walk() 函数

    array_walk() 函数对数组中的每个元素应用回调函数.如果成功则返回 TRUE,否则返回 FALSE. 典型情况下 function 接受两个参数.array 参数的值作为第一个,键名作为第二 ...

  10. LINQ Operators之过滤(Filtering)

    转:http://www.cnblogs.com/lifepoem/archive/2011/11/16/2250676.html 在本系列博客前面的篇章中,已经对LINQ的作用.C# 3.0为LIN ...