线性表——顺序存储结构

一)声明

  新手上路。如果有不对的,不合理的地方,编码风格,算法思路有待改进的地方,还请各位大神多多指点。

二)简介  

  本文中采用动态开辟内存的方法建立线性表,实现顺序表的基本操作。

  此代码思路比较简单,毕竟只是简单的原理,没有具体的应用,仅仅作为入门学习的积累。

三)具体实现分析如下:

 3.1)头文件定义如下:

 1 #ifndef LinearList_SqList_h
 2 #define LinearList_SqList_h
 3
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6
 7 #define OK 1
 8 #define ERROR 0
 9
10 #define LIST_INIT_SIZE 100
11 #define SIZE_INCREMENT 10
12
13 typedef int Status;
14 typedef int ElemType;
15
16 typedef struct {
17     ElemType *pElem;
18     int nLength;
19     int nListSize;
20 }SqList;
21
22
23 void InitSqList(SqList *L);
24 Status InsertSqList(SqList *L, int nIndex, ElemType eValue);
25 Status AssignSqList(SqList *L);
26 Status DeleteSqList(SqList *L, int nIndex, ElemType *pValue);
27 Status ClearSqList(SqList *L);
28 Status DestroySqList(SqList *L);
29 Status LocateElem(SqList L, ElemType nValue);
30 Status PrintSqList(SqList L);
31
32 #endif

SqList.h

 3.2)具体实现:

  3.2.1)基本原则:

    a)函数参数中,只要传递的是指针,函数内必须首先校验指针是否为空。

    b)如果要对顺序表进行修改,那么必须进行地址传递,而不是值传递。

    c)malloc申请的内存,一定要用free释放,并且释放之后,置指针为空,防止出现也指针。

  3.2.2)具体代码思路:

  a、InitSqList

  动态申请空间,依此对顺序表的成员赋值。

  b、InsertSqList (此处允许对空表进行插入)

  思路:校验指针参数——》校验插入点——》校验顺序表是否已初始化——》校验顺序表是否已满——》遍历顺序表,找到插入点——》移动元素——》插入——》同时表长增加;

  分析:其实真正的插入就是一行代码,但是为了保证插入后不影响其他元素的使用,必须移动元素;为了保证程序的健壮性,必须增加很多校验过程;

      重点在于下标的计算。

    2.1参数校验:指针是否为空;插入点是否非法

    2.2顺序表校验:顺序表是否已初始化;对于插入而言,顺序表是否已满;

    2.3当所有的校验完毕之后,寻找正确插入点,移动元素(从表尾向待插入点方向遍历),最后插入,增加表长;

    (2.4)关于空表是否允许插入的问题:根据不同的需求和功能设定。如果不允许对空表插入,可以多加一层校验功能即可;(此处允许空表插入)

  c、DeleteSqList (基本原理类似于Insert)

   思路:校验指针参数——》校验删除点——》校验顺序表是否初始化——》校验顺序表是否为空——》遍历顺序表,寻找删除点——》移动元素——》删除——》同时表长自减;

    分析:删除元素就是不断的移动元素,采用覆盖原理即可(从删除点向表尾方向遍历)。关键是下标的计算。

  d、DestroySqList

    思路:校验指针参数——》校验顺序表是否初始化——》释放申请的内存——》同时设置顺序表相关参数。

    分析:重点在于参数的校验和free过后的指针应该置空。

  3.3)具体代码如下:

  

  1 #include "SqList.h"
  2
  3 void InitSqList(SqList *L) {
  4     if (NULL == L) {
  5         printf("Error parament.");
  6         return ;
  7     }
  8
  9     L->pElem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(SqList));
 10     if (NULL == L->pElem) {
 11         printf("Error:Out of memory.");
 12         return ;
 13     }
 14
 15     L->nLength = 0;
 16     L->nListSize = LIST_INIT_SIZE;
 17 }
 18
 19
 20 //Insert element to sqlist
 21 Status InsertSqList(SqList *L, int nIndex, ElemType eValue) {
 22     if (NULL == L) {
 23         printf("Error parament.");
 24         return ERROR;
 25     }
 26
 27     if (NULL == L->pElem) {
 28         printf("Error: The list is not initiated.");
 29         return ERROR;
 30     }
 31
 32     if (nIndex < 1 || nIndex > L->nLength + 1) {
 33         printf("Error: Invalid insert point.");
 34         return ERROR;
 35     }
 36
 37     ElemType *pNewBase;
 38     if (L->nLength >= L->nListSize) {
 39         pNewBase = (ElemType*)realloc(L->pElem, (LIST_INIT_SIZE + SIZE_INCREMENT) * sizeof(ElemType));
 40         if (NULL == pNewBase) {
 41             printf("Error:Out of memory.");
 42             return OK;
 43         }
 44         //here can also write with ‘else‘.
 45         //Logically no problem. But it takes effort to write the else and ‘{}‘. Efficiently not good choice
 46         L->pElem = pNewBase;
 47         L->nListSize += SIZE_INCREMENT;
 48     }
 49
 50     ElemType *pInsert, *pLast;
 51     pInsert = L->pElem + nIndex - 1;
 52     pLast = L->pElem + L->nLength - 1;
 53
 54
 55     while (pLast >= pInsert) {
 56         *(pLast + 1) = *pLast;
 57         pLast--;
 58     }
 59
 60     *pInsert = eValue;
 61     ++L->nLength;
 62
 63     return OK;
 64 }
 65
 66 //Assign sqlist
 67 Status AssignSqList(SqList *L) {
 68     if (NULL == L) {
 69         printf("Error parament.");
 70         return ERROR;
 71     }
 72
 73     if (NULL == L->pElem) {
 74         printf("Error:The list is not initiated.");
 75         return ERROR;
 76     }
 77
 78     int nLength, nValue;
 79     printf("Input the length:");
 80     scanf("%d", &nLength);
 81
 82     for (int i = 1; i <= nLength; i++) {
 83         printf("Input the value:");
 84         scanf("%d", &nValue);
 85
 86         InsertSqList(L, i, nValue);
 87     }
 88
 89     return OK;
 90 }
 91
 92 //delete element from sqlist
 93 Status DeleteSqList(SqList *L, int nIndex, ElemType *pValue) {
 94     if (NULL == L || NULL == pValue) {
 95         printf("Error parament.");
 96         return ERROR;
 97     }
 98
 99     if (NULL == L->pElem) {
100         printf("Error:The list is not initiated.");
101         return ERROR;
102     }
103
104     if (L->nLength <= 0) {
105         printf("Error:The list is empty.Can‘t delete.");
106         return ERROR;
107     }
108
109     if (nIndex < 1 || nIndex > L->nLength) {
110         printf("Error:Invalid delete index.");
111         return ERROR;
112     }
113
114     ElemType *pDelete, *pLast;
115     pDelete = L->pElem + nIndex - 1;
116     pLast = L->pElem + L->nLength - 1;
117
118     *pValue = *pDelete;
119     for (pDelete++; pDelete <= pLast; pDelete++) {
120         *(pDelete - 1) = *pDelete;
121     }
122
123     --L->nLength;
124
125     return OK;
126 }
127
128 //clear sqlist
129 Status ClearSqList(SqList *L) {
130     if (NULL == L) {
131         printf("Error parament.");
132         return ERROR;
133     }
134
135     if (NULL == L->pElem) {
136         printf("Error: The list is not initiated.");
137         return ERROR;
138     }
139
140     L->nLength = 0;
141
142     return OK;
143 }
144
145 //destroy sqlist
146 Status DestroySqList(SqList *L) {
147     if (NULL == L) {
148         printf("Error parament.");
149         return ERROR;
150     }
151
152     if (NULL == L->pElem) {
153         printf("Error:The list is not initiated.");
154         return ERROR;
155     }
156
157     free(L->pElem);
158     L->pElem = NULL;
159     L->nLength = 0;
160     L->nListSize = 0;
161
162     return OK;
163 }
164
165 //locate element from sqlist
166 Status LocateElem(SqList L, ElemType nValue) {
167     if (NULL == L.pElem) {
168         printf("Error:The list is not initiated.");
169         return ERROR;
170     }
171
172     if (L.nLength <= 0) {
173         printf("Error:The list is empty.");
174         return ERROR;
175     }
176
177     int nIndex;
178     ElemType *pLocate = L.pElem;
179
180     for (nIndex = 1; nIndex <= L.nLength; nIndex++) {
181         if (nValue == *pLocate) {
182             printf("Located succeeded.");
183             return nIndex;
184         }
185         pLocate++;
186     }
187
188     return ERROR;
189 }
190
191
192 //Print sqlist
193 Status PrintSqList(SqList L) {
194     if (NULL == L.pElem) {
195         printf("Error:The list is not initiated.");
196         return ERROR;
197     }
198
199     if (L.nLength <= 0) {
200         printf("The list is empty.");
201         return ERROR;
202     }
203
204     printf("The list is as follows:");
205     for (int i = 1; i <= L.nLength; i++) {
206         printf("%d ", *L.pElem);
207         L.pElem++;
208     }
209
210     printf("\n");
211     return OK;
212 }

SqList.c

  

  

时间: 2024-10-10 07:52:46

线性表——顺序存储结构的相关文章

数据结构——线性表顺序存储结构

 关于线性表 线性表是零个或者多个数据元素的集合.它主要有以下三个特征: 1:线性表的数据元素之间是有顺序的. 2:线性表中数据元素个数是有限的. 3:线性表中数据元素数据类型是相同的. 关于线性表的操作,主要有 创建线性表.销毁线性表.清空线性表.将元素插入线性表.将元素从线性表中删除.获取线性表中某个位置的元素.获取线性表的长度. 线性表主要有两种存储结构: 1:线性表的顺序存储结构,c语言中的数组及采用这种方式. 2:线性表的链式存储结构. 关于顺序存储结构 定义: 是指用一段地址连续的内

数据结构与算法-线性表顺序存储结构删除操作的实现

这一章节我们来看一下线性表顺序存储结构删除操作的简单实现 package com.ray.testobject; public class Test { private Object[] list; public Object[] getList() { return list; } /** * 初始化list * * @param num * 元素个数 */ private void iniList(int num) { list = new Object[num]; for (int i =

数据结构与算法-总结线性表顺序存储结构的优缺点

这一章节主要总结线性表顺序存储结构的优缺点. 在总结之前,我们来讨论一下线性表顺序存储结构的执行方法的时间复杂度: 存储.读取:O(1) 插入.删除:O(n) 优点: 1.无需为表中的逻辑关系增加额外的存储空间 2.可以快速存取表中对象 缺点: 1.插入和删除需要移动大量的对象 2.存储设备的碎片化 3.当线性表过大的时候,很难确定长度 版权声明:本文为博主原创文章,未经博主允许不得转载.

线性表顺序存储结构的c语言实现

线性表顺序存储结构用C实现的操作 <1>声明一个线性表的顺序存储结构 <2> 初始化顺序线性表 <3>判断是否为空 <4>清空列表 <5>返回当前长度(线性表内元素个数) <6>返回L中第i个数据元素的值,注意i是指位置,第1个位置的数组是从0开始 <7>返回L中第1个与e满足关系的数据元素的位序.若这样的数据元素不存在,则返回值为0 <8>在L中第i个位置之前插入新的数据元素e,L的长度加1 <9>

线性表—顺序存储结构

线性表——顺序存储结构 我理解的顺序存储就是 存储的一组元素在内存中呈线性排列,地址相邻,就像火车一样,每个车厢都可以看做是一个元素,元素门内首尾相连且地址相邻,书看的是高一凡老师的书,学完后自己写一下总结和体会,一来加深印象,二来可以方便自己复习. 顺序存储结构似乎都是用数组来实现的,也就是以数组为核心,外面加了许多很方便的操作(函数)进行封装,然后就说这叫[顺序存储结构]——数组的深加工之后的产品 顺序存储结构的基本功能有以下几个: name:     sqlist private: T *

线性表-顺序存储结构

线性表-顺序存储结构 顺序存储结构 线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素 三个属性 存储空间的起始位置:数组data,它的存储位置就是存储空间的存储位置 线性表的最大存储容量:数组的长度MaxSize 线性表的当前长度:length 数据长度和线性表长度的区别 数据长度就是数组的长度,存放线性表的存储空间的长度,存储分配后这个量一般是不变的 线性表长度是线性表中数据元素的个数,随着线性表的删除插入操作,这个长度是改变的 在任何时刻,数组的长度大于等于线性表

数据结构与算法——线性表顺序存储结构

今天总结一下数据结构中的线性表中的顺序存储结构,这是一种比较简单的结构. 首先,看一下什么是线性表. 什么是线性表? 线性表是一种简单的数据结构,数据元素之间是一对一的关系,即除了第一个和最后一个元素外其余元素都是首尾相接的.元素的个数称为线性表的长度,长度为零则表示线性表为空. 什么是线性表的循序存储结构? 线性表中的顺序存储结构就是把线性表中的元素按逻辑次序依次存放在一组地址连续的存储空间中,也把这种线性表称为顺序表.根据顺序表的特点,通常是用数组来存储元素的. 下面就看具体的实现(C++)

数据结构 - 线性表顺序存储结构

线性表 线性表是一种典型的线性结构.其基本特点是线性表中的数据元素是有序且是有限的.在这种结构中: ① 存在一个唯一的被称为"第一个"的数据元素: ② 存在一个唯一的被称为"最后一个"的数据元素: ③ 除第一个元素外,每个元素均有唯一一个直接前驱: ④ 除最后一个元素外,每个元素均有唯一一个直接后继. 线性表(Linear List) :是由n(n≧0)个数据元素(结点)a1,a2, -an组成的有限序列.该序列中的所有结点具有相同的数据类型. 线性表中的数据元素

线性表顺序存储结构的优缺点

优点:1.无须为表示表中元素之间的逻辑关系而增加额外的存储空间. 2.可以快速的存取表中任一位置的元素. 缺点:1.插入和删除操作需要移动大量的元素. 2.当线性表长度变化较大时,难以确定存储空间的容量. 3.造成存储空间的"碎片". ======================================== 可是有一点需要注意,可以快速的存取表中任一位置的"存",和"插入"有什么区别呢? "存"的意思表达的就是给线性表

线性表-顺序存储结构(即数组)

1.定义 线性表:零个或多个元素组成的有限序列.第一个无前驱,最后一个无后继,其余元素都有一个前驱和后继.元素的个数为n. 数据类型:是指一组性质相同的值的集合及定义在此集合上的一些操作的总称.例如,编程语言中的整型,浮点型等. 抽象数据类型ADT:对数据类型进行抽象,抽取出事务具有的普遍性的本质,是特征的概括,而不是细节.(数据类型和相关的操作捆绑在一起) 线性表抽象数据类型(List): Data:线性表的数据对象集合为{a,b,c...},每一个元素的数据类型为DataType Opera