線性表的順序存儲結構
特點:
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;
}