您的位置:首页 > 理论基础 > 数据结构算法

数据结构算法代码实现——线性表的顺序表示与实现(二)

2015-05-28 20:28 501 查看

线性表的顺序表示

线性表的顺序表示:指的是一组地址连续的存储单元依次存储线性表的数据元素。


顺序表的存储方法与特点

在日常生活中,我们通常更喜欢使用连续的存储空间来存放各种物品。

好,举个例子:假设宿舍内的床铺用编号1-6,宿舍内成员按年龄分出老大-老六,老大使用编号为1的床铺。依次类推。
这种安排方式可以使我们通过床铺编号快速找到同学。

顺序表的存储方式也与此类似,下面讨论顺序表的特点:
1. 顺序存储结构的逻辑存储和存储结构一致
2. 访问每个数据元素所花费的时间相同,利用数学公式
3. 存取元素的方法称为随机存取法,也称为随机存储结构。


顺序存储结构表示

//----线性表的动态分配顺序存储结构----
#define LIST_INIT_SIZE 10 //线性表存储空间的初始分配量
#define LISTADD 5  //线性表存储空间的分配增量
typedef struct {
ElemType * elem; //存储空间基址(数组的基地址)
int length;//当前长度
int listsize;//当前分配的存储总容量(sizeof(ElemType)为单位)
}Sqlist;


见严蔚敏教材22页。

顺序表的基本操作(C语言)

基本操作包括了教材19页的12个操作,其中的操作也实现了教材中的2.3,2.4,2.5,2.6算法。

C语言代码:

1,先给出头文件:

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status; //Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean; // Boolean是布尔类型


2,在给出基本操作代码:

3,然后给出测试上述操作的C代码:

测试:

4,最后在给出测试结果图:



5,总结

上述操作中需要重点掌握的算法是,初始化、插入、删除等等。比较重点的基本操作在代码中都有自然语言算法描述和注释。
如需详细了解,请见教材。
下面,我们简单了解一下比较重要操作的问题:
1,书中算法2.4是插入操作:
假定插入线性表中任一元素的概率相同(都为1/n+1),则插入一个元素平均需要移动元素的个数是n/2。
个数取决于插入的位置,假定在顺序表任何插入位置的概率是相等的,则平均情况下,需要移动一半的数据元素。

2,书中算法2.5是删除操作:
假定删除线性表中任一元素的概率相同(都为1/n),则删除一个元素平均需要移动元素的个数是(n-1)/2。
删除的时间复杂度也是O(n)。

3,书中算法2.6是根据满足关系执行操作
基本操作是“进行两个元素之间的比较”,需要遍历表中的数据元素与e比较。可见时间复杂度与表的长度有关,
所以时间复杂度为O(L.length)。


较复杂的操作算法实现

上述的算法是一些基本的操作,教材中的2.1,2.2,2.7算法是较复杂的算法(多种基本操作的组合使用)。
合并后的表仍然是非递减有序排列。


1. 算法2.1

C语言算法实现:

结果图:



2. 算法2.2和算法2.7 和 书中26页对2.7的改进算法 都在下述代码中

需要一个计算时间的文件,用于测试不同算法的时间:

```
#include <windows.h>

void kaishi(DWORD *start){
*start = GetTickCount();

}
void end(DWORD *stop){
*stop = GetTickCount();
}
void time_printf(DWORD start,DWORD stop){
printf("time: %lld ms\n", stop - start);
}
```


C语言算法实现:

首先看算法结果测试图:



然后看不同算法的时间比较图(含2.1算法union())

对于时间的比较 在最后被注释的代码,可以自行修改代码进行不同算法的时间比较 。下面我们进行两次比较:算法2.1
、算法2.2的比较 和算法2.2与2.7的比较。


(1)算法2.1、算法2.2的比较结果图:



(2)算法2.2 、算法2.7的比较结果图



3. 总结

对于算法的评论,可以依据时间复杂度,当然这不是评价的唯一标准。

1,首先先看算法2.1:
在此算法中的一些基本操作如GetElem、ListInsert(在表尾插入)的执行时间复杂度和表长无关。LocateElem
的执行时间和表长成正比,所以算法2.1的时间复杂度为O(ListLength(LA) * ListLength(LB))。
2,在看算法2.2:
在此算法的基本操作和算法2.1相同,但是算法时间复杂度却不同,算法2.2的时间复杂度为O(ListLength(LA) + ListLength(LB))。
从上面的时间比较图(1),就可以看出在有100000条数据时,算法2.2相对算法2.1节省了1800倍。
3,最后看算法2.7:
在此算法中的基本操作是“元素赋值”,没有上述的一些基本操作。它的时间复杂度也是O(ListLength(LA) + ListLength(LB))。
但是从上面的时间比较图(2),可以看出算法2.7相对算法2.2节省了230倍的时间。所以当两个算法的时间复杂度相同,但是由于不同的基本操作,
可能会有很多的解决方案,我们要选择最优的解决方案,否则在对于大数据的问题将很难解决。
4,算法2.7的改进是为了达到2.1的效果,具体的分析可见教材。注意的是,算法2.1只是链接两个表并去掉重复元素,想将Lb中元素插入La,
算法2.7的改进需要先对表进行数据元素的排序。由此可见,若以线性表表示集合并进行集合的各种运算,应先对表中元素进行排序。


最后讨论一下顺序存储的缺点

人无完人,金无赤足。在数据结构中也是如此,顺序表既然有特点、有优点,顺序表的缺点:


对顺序表做插入、删除时,需要大量的移动数据元素。

线性表需要预先分配空间,必须按最大空间分配,存储空间得不到充分利用,造成内存浪费。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: