首先是我们顺序表的储存结构:
typedef struct{
ElemType* elem;
int length;
int listsize;
}Sqlist;
elem表示数组指针,length表示顺序表中元素的个数,listsize表示顺序表我们能接受的最多的元素个数,如果length == listsize的时候就说明顺序表已经满了,我们就需要使用realloc()函数来进行扩容。
然后就是我们需要实现的功能:
初始化、建表操作
InitList(&L);这里传递过去的都是指针,所以这里要用引用的形式,返回操作状态
销毁顺序表
DestroyList(&L);返回操作状态
清空顺序表
ClearList(&L);返回操作状态
判断顺序表是否为空
ListEmpty(L);返回0或者1,是否为空的状态
得到循序表的长度
ListLength(L);返回长度整数
得到L中第i个元素的值
GetElem(L,i,&e);返回操作状态,并且用e带回
找到第一个数值为e,并且返回相应的位置
LocateElem(L,e,equal);如果找不到则返回0
得到一个元素的前驱
PriorElem(L,e,&per_e);用per_e带回答案,返回操作后的状态
得到一个元素的后继
NextElem(L,e,&next_e);用next_e带回答案,返回操作后的状态
在相应的位置插入元素
ListInsert(&L,pos,num);在pos位置插入num,返回操作之后的状态
删除相应位置的元素
ListDelete(&L,pos,&num);删除pos位置的元素,用num带回,返回操作之后的状态
便利顺序表L输出元素
ListTraverse(L,print);便利输出顺序表,返回操作之后的状态
最后的实现过程:
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
//顺序表的存储结构定义
#define LIST_INIT_SIZE 100
#define LISTADD 10
typedef int ElemType; //假设线性表中的元素均为整型
typedef struct{
ElemType* elem;
int length;
int listsize;
}Sqlist;
Status equal(ElemType c1,ElemType c2)//返回位置函数所传递的参数
{
//判断是否相等的函数
if(c1==c2)
return TRUE;
else
return FALSE;
}
// 1, InitList(&L) 操作结果:构造一个空的顺序表L
Status InitList(Sqlist &L){
L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem) exit(OVERFLOW);//exit(-1) 存储空间失败
L.length=0; //初始化空表长度为0
L.listsize=LIST_INIT_SIZE; //初始化空表的存储总容量
return OK; //返回状态码 1
}
// 2, DestroyList(&L) 初始条件:顺序表L已存在。 操作结果:销毁顺序表L。
Status DestroyList(Sqlist &L){
free(L.elem);
L.elem=NULL; //指向空
L.length=0;
L.listsize=0;
return OK;
}
//3, ClearList(&L) 初始条件:顺序表L已经存在。操作结果:将L重置为空表。
Status ClearList(Sqlist &L){
L.length=0; //清空当前长度
return OK;
}
//4, ListEmpty(L) 初始条件:顺序表L已存在。操作结果:若顺序表L为空返回TRUE,否则返回FLASE。
Status ListEmpty(Sqlist L){
if(L.length==0)
return TRUE;
else
return FALSE;
}
//5, ListLength(L) 初始条件:顺序表L已存在。操作结果:返回L中数据元素的个数。
int ListLength(Sqlist L){
return L.length;
}
//6, GetElem(L,i,&e) 初始条件:顺序表L已存在(1<=i<=ListLength(L))。操作结果:用e返回L中i个数据元素的值。
Status GetElem(Sqlist L,int i,ElemType &e){
if(i<1||i>L.length)
exit(ERROR);
e=L.elem[i-1];//*e=*(L.elem+i-1)
return OK;
}
//7, LocateElem(L,e,compare()) 初始条件:顺序表L已存在,compare()的数据元素判定函数。
// 操作结果:返回L中第1个与e的满足关系compare()的数据元素的位序。若这样的数据元素不存在,则返回0.
int LocateElem(Sqlist L,ElemType e,Status (*compare)(ElemType,ElemType)){//compare()形参是函数指针
int i =1; //i的初值为第一个元素的位序
ElemType *p=L.elem; //p的初值为第一个元素的存储位置
while(i<=L.length && !(*compare)((*p++),e)){
++i;
}
if(i<=L.length)
return i;
else
return 0;
}
//8, PriorElem(L,cur_e,&pre_e) 初始条件:顺序表L已存在。
//操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义。
Status PriorElem(Sqlist L,ElemType cur_e,ElemType &pre_e){
ElemType *p =L.elem+1; //指针变量p 指向第二个数据元素
int i =2;
while(i<=L.length && (*p)!=cur_e){ //注意不能写成,(*p++)!=cur_e,虽然它先判断*p,在+1,
//但是在条件不成立时会多后移一个位置
p++;
++i;
}
if(i>L.length){
return ERROR;
}else{
pre_e=(*--p); //p先自减,pre_e就指向该数据元素的前驱结点
return OK;
}
}
//9, NextElem(L,cur_e,&next_e) 初始条件:顺序表L已存在。
//操作结果:若cur_e是L的数据元素,且不是第一个,则用next_e返回它的前驱,否则操作失败,next_e无定义。
Status NextElem(Sqlist L,ElemType cur_e,ElemType &next_e){
ElemType *p =L.elem;
int i=1;
while(i<L.length && (*p)!=cur_e){
p++;
++i;
}
if(i>=L.length){
return ERROR;
}else{
next_e =(*++p); //next_e指向该数据元素的后继结点
return OK;
}
}
//10, ListInsert(Sqlist *L,i,e) 初始条件:顺序表L已存在,1<=i<=ListLength(L)+1。
//操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1
Status ListInsert(Sqlist &L,int i,ElemType e){
if(i < 1 || i > L.length+1)//可以插入的最前面或者是最后面坐标分别为(1,L.length+1)
exit(ERROR);
if(L.length +1 == L.listsize)
{
L.elem = (ElemType *)realloc(L.elem,sizeof(L.listsize + LISTADD));
L.length += LISTADD;
}
for(int pos = L.length-1 ;pos >= i-1; pos --)
L.elem[pos+1] = L.elem[pos];
L.elem[i-1] = e;
L.length ++;
return OK;
}
//11, ListDelete(Sqlist &L,int i,ElemType &e) 初始条件:顺序线性表L已存在,1<=i<=ListLength(L)
Status ListDelete(Sqlist &L,int i,ElemType &e){
if(i < 1 || i > L.length )
exit(ERROR);
e = L.elem[i-1];
for(int pos = i-1;pos < L.length-1; pos ++)
L.elem[pos] = L.elem[pos+1];
L.length --;
return OK;
}
//12, ListTraverse(L) 初始条件:顺序线性表L已存在。
Status ListTraverse(Sqlist L){
for(int i=0;i<L.length;i++)
{
if(i)
printf(" %d",L.elem[i]);
else
printf("%d",L.elem[i]);
}
printf("\n");
}
int main()
{
Sqlist L;
InitList(L);
DestroyList(L);
ClearList(L);
int k=ListEmpty(L);
int len=ListLength(L);
int e,index,per_e,next_e,num;
GetElem(L,index,e);
LocateElem(L,e,equal);
PriorElem(L,e,per_e);
NextElem(L,e,next_e);
int pos;
ListInsert(L,pos,num);
ListDelete(L,pos,num);
ListTraverse(L);
}
如果程序有错误的话,我会第一时间改正的......
正在准备考研,所以更新了一个类模板的顺序表,功能仅仅实现了简单的插入、删除、初始化、销毁、输出等基础功能。
写完才发现,这里新建一个类来作为Node节点没有必要,可以直接忽略掉这个Node类节点,直接在SeqList类中做对应的节点数组即可!
#ifndef _LINE_TABLE_
#define _LINE_TABLE_
#define MaxSize 100
#include <iostream>
template<typename ElemType>
class Node //节点数据
{
public:
Node() = default;
Node(ElemType x):elem(x){
};
~Node() = default;
ElemType GetElem(){
return elem;
}
void SetElem(ElemType x){
elem = x;
}
private:
ElemType elem;
};
template<typename ElemType>
class SeqList //顺序表结构
{
private:
Node<ElemType> *data;
int length;
public:
SeqList(){
data = new Node<ElemType>[MaxSize];length = 0;
}
SeqList(const int& size){
data = new Node<ElemType>[size];length = 0;
}
~SeqList(){
if(data != nullptr)
delete []data;
}
void InitList(){
if(data == nullptr)
data = new Node<ElemType>[MaxSize],length = 0;
}
int Length(){
return length;
}
int LocateElem(ElemType e){
for(int i = 0;i < length;i++){
if((data+i)->GetElem() == e)
return i;
}
return length;
}
ElemType GetElem(int pos)
{
retrun (data+pos)->GetElem();
}
void ListInsert(int pos,ElemType e)
{
if(pos < 0 || pos > length) return ;
if(pos == length)
(data+pos)->SetElem(e);
else if(pos < length && pos >= 0)
{
for(int i = length;i >= pos;i --)
(data+i)->SetElem((data+i-1)->GetElem());
(data+pos)->SetElem(e);
}
length++;
}
void Delete(int pos,ElemType& e)
{
if(pos <0 || pos >= length) return ;
for(int i = pos;i < length - 1;i ++)
(data+i)->SetElem((data+i+1)->GetElem());
length--;
}
void PrintList()
{
for(int i =0;i < length;i ++)
std::cout << (data+i)->GetElem() <<" ";
std::cout << std::endl;
}
void DestoryList(){
if(data != nullptr)
delete []data;
length = 0;
}
bool Empty(){
return length == 0;
}
};
#endif
#include "Linea_table.h"
#include <iostream>
#include <cstring>
using namespace std;
int main() //测试程序
{
SeqList<Student> slist;
slist.ListInsert(0,Student(16,"WenBo"));
slist.PrintList();
int num;
SeqList<int> list;
for(int i =0 ;i < 10;i ++)
list.ListInsert(i,i);
list.ListInsert(5,100);
list.Delete(5,num);
list.Delete(4,num);
list.ListInsert(2,200);
list.PrintList();
list.DestoryList();
}