数据结构从零单排1——顺序表

来源:互联网 发布:thinkphp分销系统源码 编辑:程序博客网 时间:2024/05/22 14:22

前言

无论是考研也好工作也罢,数据结构一直是对计算机系同学们十分重要的科目(虽然我目前并不是。。),而由于学校学时的原因,数据结构这门课一直讲的很浅显,再加上学完之后没有怎么复习(简单工程性的项目里面其实并不需要用到多少数据结构),基本都忘光光了,所以我决定重刷数据结构,这个系列文章我会尽量坚持更下去的。

顺序表

顺序表是线性表的一种,又称为线性表的顺序表示,指的是用一组地址连续的存储单元一次存储线性表的数据元素,从定义上一个抽象的线性表主要包含三种元素:
  1. 存储空间首地址
  2. 当前长度
  3. 当前总共分配的存储容量

根据这三个元素我们可以构造出一个顺序表的抽象数据类型。

顺序表的实现

1.数据类型定义
#define LIST_INIT_SIZE 100 //线性表存储空间初始分配量#define LIST_INCREMENT 10 //线性表存储空间分配增量typedef struct{int *start; //顺序表基址int length; //顺序表长度int listSize; //顺序表存储容量}SqList;

2.功能实现,主要实现了插入,删除和两个顺序表的合并,注释很清楚,不多解释了
#include <stdio.h>#include <stdlib.h>#include <Windows.h>#include "SqListTest.h"int initList(SqList *L);int insertData(SqList *L, int index, int data);int deleteData(SqList *L, int index, int *data);SqList * unionList(SqList *La, SqList *Lb);int main(void) {SqList *list = (SqList *)malloc(sizeof(SqList));if (initList(list)){int *temp = (int *)malloc(sizeof(int));insertData(list, 1, 2);insertData(list, 1, 3);insertData(list, 3, 5);deleteData(list, 3, temp);for (int i = 0;i < list->length;i++){printf("%d\n", list->start[i]);}printf("华丽分割线----------------------------------------------------------\n");}SqList *La = (SqList *)malloc(sizeof(SqList));SqList *Lb = (SqList *)malloc(sizeof(SqList));if (initList(La) && initList(Lb)){insertData(La, 1, 1);insertData(La, 2, 6);insertData(La, 3, 9);insertData(Lb, 1, 2);insertData(Lb, 2, 5);insertData(Lb, 3, 7);SqList *Lc = unionList(La, Lb);for (int i = 0;i < Lc->length;i++){printf("%d ", Lc->start[i]);}}system("pause");return 0;}//初始化顺序表int initList(SqList *L) {L->start = (int *)malloc(LIST_INIT_SIZE * sizeof(int));if (!L->start){printf("存储分配失败");return 0;}L->length = 0;L->listSize = LIST_INIT_SIZE;return 1;}/************************************************************************//* 插入数值/* L:顺序表/* index:插入的位置/* data:插入的数值/************************************************************************/int insertData(SqList *L, int index, int data) {//若插入位置不合法,插入失败if (index < 1 || index > L->length + 1){return 0;}//若顺序表已满if (L->length > L->listSize){//新分配一块空间int *newSpace = (int *)realloc(L->start, (L->listSize + LIST_INCREMENT) * sizeof(int));if (!newSpace){return 0; //存储分配失败}L->start = newSpace; //新基址L->listSize += LIST_INCREMENT; //存储容量增加}int q;//移动数值,将待插入的地址置空for (q = L->length - 1;q >= index - 1;q--){L->start[q + 1] = L->start[q];}L->start[index - 1] = data;L->length++;return 1;}/************************************************************************//* 删除                                                                     *//************************************************************************/int deleteData(SqList *L, int index, int *data) {//若位置不合法if (index < 1 || index > L->length){return 0;}//记录被删除的数值*data = L->start[index - 1];//遍历覆盖for (int i = index - 1;i < L->length - 1;i++){L->start[i] = L->start[i + 1];}//更新表的长度L->length--;return 1;}/************************************************************************//* 两个递增顺序表的合并                                                                     *//************************************************************************/SqList * unionList(SqList *La, SqList *Lb) {//pa,,pb用于记录两个顺序表的首地址int *pa = La->start;int *pb = Lb->start;SqList *Lc = (SqList *)malloc(sizeof(SqList)); //创建Lc,并分配空间if (!Lc){return 0;}Lc->start = (int *)malloc((La->length + Lb->length) * sizeof(int));//lc长度为两表长度之和Lc->listSize = Lc->length = La->length + Lb->length;if (!Lc->start){return 0;}int *pc = Lc->start;int *pa_last = La->start + La->length - 1;int *pb_last = Lb->start + Lb->length - 1;//当pa,pb都没有到达顺序表底部时,比较两者的值赋值给pcwhile(pa <= pa_last && pb <= pb_last) {if (*pa < *pb){*pc++ = *pa++;} else {*pc++ = *pb++;}}//pa,pb有一个到达底部直接将剩余值给LCwhile(pa <= pa_last) {*pc++ = *pa++;}while(pb <= pb_last) {*pc++ = *pb++;}return Lc;}
可以看到,顺序表的特点为,访问某个位置很容易,而在插入或者删除数据时,由于要进行大量的移位操作,所以效率很低那么可以得出结论:
  • 如果需要使用的线性表需要做大量的查询访问工作,而很少对线性表进行插入删除工作,那么可以选择顺序表的数据结构
原创粉丝点击