线性表的顺序存储结构
特点:
1、物理地址相邻
2、随机存取:可以计算出每个数据元素的存储地址(数组)
在数据结构(严蔚敏C语言)中,顺序表实现的代码如下:
时间复杂度的分析:
顺序表时间主要花费在移动元素中,移动元素的个数取决于插入或删除元素的位置
结论:
顺序表中插入或删除一个数据元素,平均移动一半的元素
算法ListInsert_Sq和ListDelete_Sq的时间复杂度为O(n)
//初始化文件
#ifndef _INIT_H
#define _INIT_H
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define TRUE 1
#define FALLSE 0
#define OK 1
#define ERROR -1
#define OVERFLOW NULL
typedef int Status;
#endif
头文件
#ifndef _SEQUENCE_H
#define LISTSIZE 100
#define LISTINCEREMENT 10
typedef int Item;
typedef struct
{
Item add[LISTSIZE];
int length;
}SqList;
Status init_sqlist(SqList &L);
Status insert_list(SqList &L,int i,Item e);//插入元素e到顺序列表的第i个位置
Status delete_list(SqList &L,int i,Item &e);//删除第i个元素并返回给e;
Status display_list(SqList);
Status merge_list(SqList La,SqList Lb,SqList &Lc);//合并两个顺序列表
#endif
.cpp文件
#include "init.h"
#include "Sequence.h"
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
Status init_sqlist(SqList &L)//构造空表L
{
L.length=0;
return OK;
}
Status insert_list(SqList &L,int i,Elemtype e)//插入e元素到第i位
{
if (i<1||i>L.length+1)
{
return ERROR;//i值不合法
}
if (L.length>=L.listsize)//超出原有的存储容量,需要重新分配
{
Elemtype *newbase;
newbase=(Elemtype *)realloc(L.elem,(L.listsize+LISTINCEREMENT)*sizeof(Elemtype));
if (!newbase)
{
exit(OVERFLOW);
}
L.elem=newbase;//新基址
L.listsize +=LISTINCEREMENT;//增加的存储容量
}
Elemtype *q,*p;
q=&L.elem[i-1];//q为插入位置
for (p=&L.elem[L.length-1];p>=q;--p)
{
*(p+1)=*p;
}//插入位置及之后元素的位置右移
*q=e;//插入e
++L.length;//表长增加1
return OK;
}
Status delete_list(SqList &L,int i,Item &e)//在顺序表中删除第i个元素,返回e值
{
if (i<1||i>L.length)
{
return ERROR;
}
Item *p,*q;
p=&L.add[i-1];//p为被删除的元素的位置
e=*p;//被删除的元素赋值给e
q=L.add+L.length-1;//表尾元素的位置
for (++p;p<=q;++p)
{
*(p-1)=*p;
}//删元素后元素左移
--L.length;//表长减一
return OK;
}
Status display_list(SqList L)
{
printf("顺序表中的元素:\n");
for (int i=0;i<L.length;i++)
{
cout<<L.add[i]<<endl;
}
printf("\n");
return OK;
}
Status compare(Item *a,Item *b)
{
int i;
if(*a<*b)
i=1;//升序-1
else if(*a == *b)
i=0;
else
i=-1;
return i;
}
Status merge_list(SqList La,SqList Lb,SqList &Lc)//合并两个列表
{
Item *pa,*pb,*pc;
pa=La.add;
pb=Lb.add;
Lc.length=La.length+Lb.length;
pc=Lc.add;
if (!Lc.add)exit(OVERFLOW);//存储分配失败
while (pa<La.add+La.length && pb<Lb.add+Lb.length)//归并
{
switch (compare( pa , pb))
{
case 0:
*pc++=*pa++;
break;
case 1:
*pc++=*pa++;
break;
case -1:
*pc++=*pb++;
break;
}
}
while (pa<La.add+La.length) {
*(pc++)=*(pa++);//插入la剩余的元素
}
while (pb<Lb.add+Lb.length) {
*(pc++)=*(pb++);//插入lb剩余的元素
}
return OK;
}
在C语言中采用了malloc一块LISTSIZE 的空间,不够再通过搬家的方式remalloc新的内存。而在后来的C++中,不建议使用remalloc,以下是指定capacity实现顺序存储的源码
.h
#ifndef __MY_SEQLIST_H__
#define __MY_SEQLIST_H__
typedef void SeqList;
typedef void SeqListNode;
SeqList* SeqList_Create (int capacity);
void SeqList_Destroy(SeqList* list);
void SeqList_Clear(SeqList* list);
int SeqList_Length(SeqList* list);
int SeqList_Capacity(SeqList* list);
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);
SeqListNode* SeqList_Get(SeqList* list, int pos);
SeqListNode* SeqList_Delete(SeqList* list, int pos);
#endif //__MY_SEQLIST_H__
#include "seqlist.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
typedef struct _tag_SeqList
{
int length;
int capacity;
unsigned int *node; //int* node[]
}TSeqList;
SeqList* SeqList_Create(int capacity)
{
int ret = 0;
TSeqList *tmp = NULL;
tmp = (TSeqList *)malloc(sizeof(TSeqList));
if(tmp == NULL)
{
ret = -1;
printf("func err SeqList_Create():%d",ret);
return NULL;
}
memset(tmp,0,sizeof(TSeqList));
//根据capacity分配内存空间
tmp->node = (unsigned int *)malloc(sizeof(unsigned int*)*capacity);
if(tmp->node == NULL)
{
ret = -2;
printf("func err malloc_SeqList_Create : %d",ret);
return NULL;
}
tmp->capacity = capacity;
tmp->length = 0;
return tmp;
}
void SeqList_Destroy(SeqList* list)
{
TSeqList *tlist = NULL;
if(list == NULL)
{
return ;
}
tlist =(TSeqList *) list;
if(tlist->node !=NULL)
{
free(tlist->node);
}
free(tlist);
return ;
}
void SeqList_Clear(SeqList* list)
{
TSeqList *tlist = NULL;
if(list == NULL)
{
return ;
}
tlist =(TSeqList *) list;
tlist->capacity = 0;
tlist->length = 0;
return ;
}
int SeqList_Length(SeqList* list)
{
TSeqList *tlist = NULL;
if(list == NULL)
{
return -1;
}
tlist =(TSeqList *) list;
return tlist->length;
}
int SeqList_Capacity(SeqList* list)
{
TSeqList *tlist = NULL;
if(list == NULL)
{
return -1;
}
tlist =(TSeqList *) list;
return tlist->capacity;
}
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
{
int i =0, ret = 0;
TSeqList *tlist = NULL;
if (list == NULL || node==NULL || pos<0)
{
ret = -1;
printf("fun SeqList_Insert() err:%d \n", ret);
return ret;
}
tlist = (TSeqList*)list;
if(tlist->length >= tlist->capacity)
{
ret = -2;
printf("func err SeqList_Insert():tlist->length >= tlist->capacity():%d",ret );
return ret;
}
//位置错误判断
if (pos<0 || pos>=tlist->capacity)
{
return -3;
}
if(pos >= tlist->length)
{
pos = tlist->length;
}
for(i = tlist->length;i>pos;i--)
{
tlist->node[i] = tlist->node[i-1];
}
tlist->node[pos] = (unsigned int )node;
tlist->length++;
return 0;
}
SeqListNode* SeqList_Get(SeqList* list, int pos)
{
int i = 0;
SeqListNode *ret = 0;
TSeqList *tlist = NULL;
if(list == NULL || pos <0)
{
printf("func SeqList_Get()err()\n");
return NULL;
}
tlist = (TSeqList *)list;
ret = (void *)tlist->node[pos];
return ret;
}
SeqListNode* SeqList_Delete(SeqList* list, int pos)
{
int i;
TSeqList *tList = NULL;
SeqListNode *ret = NULL;
tList = (TSeqList *)list;
if (list==NULL || pos<0 || pos>=tList->length)
{
return NULL;
}
//赋给a3之前,要把a3元素缓存下来
ret = (SeqListNode *)tList->node[pos];
for (i=pos+1; i<tList->length; i++)
{
tList->node[i-1] = tList->node[i];
}
tList->length --;
return ret;
}