顺序表及其多种实现方式 --- C/C++
所谓顺序表,即线性表的顺序存储结构。下面给出的是数据结构---线性表的定义。
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++的更多相关文章
- 老郭带你学数据结构(C语言系列)2-线性表之动态顺序表
一.基本概念: 线性表:由n个类型相同的数据元素组成的有限序列,记为(a1,a2,--an). 线性表的特征:其中的元素存在这序偶关系,元素之间存在着严格的次序关系. 顺序存储表:线性表中的元素依次存 ...
- 数据结构之动态顺序表(C实现)
线性表有2种,分为顺序表和链表. 顺序表: 采用顺序存储方式,在一组地址连续的存储空间上存储数据元素的线性表(长度固定) 链表: 有3种,单链表.双向链表.循环链表(长度不固定) seqList.h ...
- K:顺序表和链表的比较
顺序表和链表是线性表的两种基本实现形式(链表还有多种变化形式),对于这两种实现方式,没有一种方法可以称是最好的,他们各自有着各自的特点和优缺点,适用于不同的应用场景. 与顺序表相比,链表较为灵活, ...
- 数据结构4:顺序表(线性表的顺序存储结构)及C语言实现
逻辑结构上呈线性分布的数据元素在实际的物理存储结构中也同样相互之间紧挨着,这种存储结构称为线性表的顺序存储结构. 也就是说,逻辑上具有线性关系的数据按照前后的次序全部存储在一整块连续的内存空间中,之间 ...
- 顺序表添加与删除元素以及 php实现顺序表实例
对顺序表的操作,添加与删除元素. 增加元素 如下图所示 对顺序列表 Li [1328,693,2529,254] 添加一个元素 111 ,有三种方式: a)尾部端插入元素,时间复杂度O(1); ...
- C语言实现顺序表(顺序存储结构)
顺序表(顺序存储结构)及初始化过程详解 顺序表,全名顺序存储结构,是线性表的一种.通过<线性表>一节的学习我们知道,线性表用于存储逻辑关系为"一对一"的数据,顺序表自然 ...
- 数据结构:顺序表(python版)
顺序表python版的实现(部分功能未实现) #!/usr/bin/env python # -*- coding:utf-8 -*- class SeqList(object): def __ini ...
- 数据结构顺序表删除所有特定元素x
顺序表类定义: template<class T> class SeqList : { public: SeqList(int mSize); ~SeqList() { delete[] ...
- C#线性表之顺序表
线性表是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract), 线性结构的特点是结构中的数据元素之间存在一对一的线性关系. 这种一对一的关系指的是数据元素之间的位置关系,即: ...
随机推荐
- DotNetBar v12.1.0.0 Fully Cracked
更新信息: http://www.devcomponents.com/customeronly/releasenotes.asp?p=dnbwf&v=12.1.0.0 如果遇到破解问题可以与我 ...
- C# ClickOnce deployment for Windows Services ClickOnce 部署windows service
A simple solution that I use is to merely stop the service and x-copy the files from my bin folder i ...
- Git搭建团队开发环境操作演练
模拟创建远程git仓库 1.首先创建如下目录结构: /Users/hujh/Desktop/GitTest2/GitServer/weibo weibo是我们要创建的项目 2.切换目录 $ cd /U ...
- poj1651 区间dp
//Accepted 200 KB 0 ms //dp区间 //dp[i][j]=min(dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]) i<k<j #include ...
- Ogre骨骼动画
转自:http://blog.csdn.net/yanonsoftware/article/details/1281516 OGRE的基本动画控制是很简单的,设置一个动画的操作是这样: // Set ...
- hdu 2097
ps:WA了两次好像....Sky数是三个进制下的各位数之和相等...而不是都等于22...我傻逼了... 代码: #include "stdio.h" int inp(int a ...
- Java中线程的锁和数据库中的事务隔离级别
当涉及到两个或多个线程操作同一个资源时,就会出现锁的问题. 数据库中的某一条记录或者是某一个对象中的字段,可以修改,也可以读取,一般情况下,读取的那个方法应该加锁(即用synchronized互斥), ...
- Oracle 获取用户表的字段定义
获取用户表列表: select * from user_tables; select * from all_tables; select * from dba_tables; 获取表的字段: sele ...
- HackRF实现GPS欺骗教程
硬件平台:HackRF One软件平台:MAC运行环境搭建系统平台:OS X 10.11 EI CapitanGPS终端:One Plus手机,飞行模式,仅GPS定位,GPS test App文章特点 ...
- task2
1. 邮件修改Mailtemplatereportfieldlink带<>的都改翻译${MAWBTask} 2.测试发邮件 3.找出能做成模版的所有地方,改成模版,复杂的地方记录下来