标签:
所谓顺序表,即线性表的顺序存储结构。下面给出的是数据结构---线性表的定义。
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 = 0; const int OK = 1; const int TRUE = 1; const int FALSE = 0; const int LIST_SIZE = 100; //定义顺序表结构ADT typedef struct{ int elem[LIST_SIZE]; int length; }SqList, *pList; //初始化顺序表 Status InitList(pList List) { List->length = 0; return OK; } //释放顺序表 Status DestroyList(pList List) { List->length = 0; 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 < 1 || i > List->length) return ERROR; //第i个数据元素存储在下标为i-1的数组中 *e = List->elem[i - 1]; return OK; } //判断给定数据是否为顺序表的元素 Status LocateElem(pList List, int e) { if (ListEmpty(List)) return ERROR; for (int i = 0; i < List->length; ++i) { if (e == List->elem[i]) return TRUE; } return FALSE; } //返回元素的前驱 Status PriorElem(pList List, ElemType cur_e, ElemType *pre_e) { if (0 == List->length) return ERROR; for (int i = 0; i < List->length; ++i) { if (cur_e == List->elem[i] && i != 0){ *pre_e = List->elem[i - 1]; return OK; } } return ERROR; } //返回元素cur_e的后驱 Status NextElem(pList List, ElemType cur_e, ElemType *next_e) { if (0 == List->length) return ERROR; for (int i = 0; i < List->length - 1; ++i) { if (cur_e == List->elem[i]){ *next_e = List->elem[i + 1]; return OK; } } return ERROR; } //在数据元素i之前插入新元素 Status ListInsert(pList List, int i, ElemType e) { if (i < 1 || i > List->length + 1) return ERROR; if (LIST_SIZE <= List->length) return ERROR; //q为插入位置,次位置及之后的要先移位才能在q这插入 ElemType* q = &List->elem[i - 1]; //移位 for (ElemType *p = &List->elem[List->length - 1]; p >= q; --p) *(p + 1) = *p; *q = e; ++List->length; return OK; } //删除顺序表中的第i个数据元素,并用e返回 Status ListDelete(pList List, int i, ElemType *e) { if (i < 1 || i > List->length) return ERROR; //p为需要删除的元素地址 讲后面的一层层移位就好 q为最后一位元素地址 ElemType *p = &List->elem[i - 1]; ElemType *q = &List->elem[List->length - 1]; *e = *p; //移位 while (p < q){ *p = *(p + 1); ++p; } --List->length; return OK; } //线性表的遍历 Status ListTraverse(pList List, void(*visit)(ElemType elem)) { if (ListEmpty(List)) return ERROR; for (int i = 0; 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 = 1; i <= 5; ++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 0; }
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 = 0; 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 = 0; 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 < 1 || i > List->length) return ERROR; *e = List->elem[i - 1]; return OK; } else{ return ERROR; } } //返回元素e的下标 Status LocateElem(pList List, ElemType e){ if (List){ for (int i = 0; i < List->length; ++i) { if (e == List->elem[i]) return i + 1; } return 0; } else{ return ERROR; } } //i之前插入元素 Status ListInsert(pList List, int i, ElemType e){ if (List){ //插入位置出错,报错 if (i < 1 || i > List->length + 1){ 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 - 1]; while (p > q){ *p = *(p - 1); --p; } *q = e; ++List->length; return OK; } else { return ERROR; } } //删除i处元素 Status ListDelete(pList List, int i, ElemType *e){ if (List){ if (i < 1 || i > List->length){ return ERROR; } ElemType *p = &List->elem[i - 1]; ElemType *q = &List->elem[List->length-1]; while (p < q){ *p = *(p + 1); ++p; } --List->length; return OK; } else{ return ERROR; } } Status ListPrint(pList List) { if (List){ for (int i = 0; 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 = 1; i <= 10; ++i) ListInsert(pMyList, i, i); ListPrint(pMyList); return 0; }
3.用C++实现顺序表 静态数组方式 面向对象
/************************************************************************ 用C++实现顺序表 静态数组方式 面向对象 ************************************************************************/ #include <cstdio> const bool OK = 1; const bool ERROR = 0; const bool TRUE = 1; const bool FALSE = 0; const int LIST_SIZE = 100; 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 = 1; i <= 5; ++i) Test.ListInsert(i, i); //Test.ListDelete(3, tmp); Test.ListTraverse(visit); putchar(10); return 0; } SqList::SqList(){ this->length = 0; } SqList::~SqList(){ this->length = 0; } Status SqList::ListEmpty(){ return !length; } int SqList::ListLength(){ return this->length; } Status SqList::GetElem(int i, int& e){ if (i < 1 || i > length) return ERROR; e = elem[i - 1]; return OK; } Status SqList::LocateElem(int e){ for (int i = 0; i < length; ++i) { if (e == this->elem[i]) return i + 1; } return ERROR; } Status SqList::ListInsert(int i, int e){ if (i < 1 || i > this->length + 1) return ERROR; if (this->length >= LIST_SIZE) return ERROR; //先将i位置及之后的元素后移,推荐使用指针实现 ElemType *q = &this->elem[i - 1]; //q为目标地址 for (ElemType *p = &this->elem[this->length]; p > q; --p) { *p = *(p - 1); } *q = e; ++length; return OK; } Status SqList::ListDelete(int i, int &e){ if (i < 1 || i > length) return ERROR; //从目标地址的后一个元素开始一个个往前移 ElemType *p = &elem[i - 1]; //p为目标地址 ElemType *q = &elem[length];//q为尾元素的地址 while (p < q){ *p = *(p + 1); ++p; } --length; return OK; } Status SqList::ListTraverse(void(*visit)(ElemType &e)){ if (length){ for (int i = 0; i < length; ++i) visit(elem[i]); return OK; } else{ printf("Empty List!"); return OK; } }
4.用C++和模板实现顺序表
/************************************************************************ 用C++和模板实现顺序表 ************************************************************************/ #include <cstdio> const int MAX_SIZE = 100; #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]; //为了排序查找方便,从1下标开始存储 int m_length; public: //默认构造函数,相当于InitList() SqList() :m_length(0){} //析构函数,相当于DestroyList(),但什么也不做 ~SqList(){ } //清空顺序表 void ClearList(){ m_length = 0; } //判断线性表是否为空 bool ListEmpty(){ return !m_length; } //求表长 int ListLength(){ return m_length; } //取得顺序表中的第i个元素 Status GetElem(int i, ElemType& e){ if (i < 1 || i > m_length) return ERROR; e = m_data[i]; return OK; } //返回L中第一个满足cmp()函数的元素的序号,若不存在,则返回0 Status LocateElem(ElemType e, bool(*cmp)(ElemType, ElemType)){ m_data[0] = 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 < 1 || i > m_length + 1 || m_length >= MAX_SIZE){ return ERROR; } for (int k = m_length; k >= i; --k){ m_data[k+1] = m_data[k]; } m_data[i] = e; ++m_length; return OK; } //删除L中的第i个元素并用e返回其值,且L的长度-1 Status ListDelete(int i, ElemType& e){ if (i < 1 || i > m_length) return ERROR; for (int j = i; j < m_length; ++j){ m_data[j] = m_data[j + 1]; } --m_length; return OK; } //线性表的遍历,依次对每个元素调用visit函数 Status ListTraverse(void(*visit)(ElemType e)){ if (m_length == 0){ printf("Empty SqList"); return ERROR; } for (int i = 1; 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 = 1; i <= n; ++i){ scanf("%d", &tmp); L.ListInsert(i, tmp); } L.ListDelete(3, tmp); L.ListTraverse(visit); printf("\n"); }
标签:
原文地址:http://www.cnblogs.com/tommychok/p/5084447.html