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;
}
 

源碼

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