C/C++数据结构:线性表的顺序存储

线性表的顺序存储结构

特点:
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;
}
 

源码

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章