赞
踩
本篇文章及后面几篇文章将会详细介绍和学习数据结构线性表中的顺序表和链表,这两种数据结构将是学习其他数据结构的基础。
文章内容结构如下:
①理论基础
②画图详细讲解
③代码实现
④常见oj题刷题
线性表(linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
理解: 数据结构实际上分两种结构:
1、物理结构(内存中如何存放的)
2、逻辑结构(是我们想象出来的)
在之前的学习中,我们提及到程序中内存区域的划分,如图:
如果我们按照物理结构将数据结构进行分类,实际上仅有两种:
①物理结构上,数据连续存储的-- - 数组(物理上连续,逻辑上也连续,缺点:数组大小固定,可能导致内存浪费)
②物理结构上,数据不连续存储的-- - 链式结构(物理上不连续,逻辑上连续,优点:内存可以按需分配)
线性:类似于一条直线,一个元素连接另外一个元素,具有连续性。
线性表的线性指的是逻辑结构上的线性,而不是物理结构上的线性,
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。(基于对数据操作的位置,将其分为头部、尾部、中间 / 任意位置)
理解:顺序表是线性表其中的一种,顺序表实际上就是数组的一种应用,C语言写顺序表的时候一般喜欢命名为SeqList,而在C++中名称为Vector(向量)
顺序表与数组的区别和联系?
(1)顺序表是在计算机内存中以数组的形式保存的线性表。
(2)顺序表是指用一组地址连续的存储单元依次存储数据元素的线性结构。线性表采用顺序存储的方式存储就称之为顺序表,顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。线性表采用指针链接的方式存储就称之为链表。
(3)线性表是从逻辑结构的角度来说的,除了头和尾之外,它的每一个元素都只有一个前驱元素和一个后驱元素。各种队列(单向、双向、循环队列),栈等都是线性表的不同例子。
(4)而数组是从物理存贮的角度来说的,线性表可以用数组存贮也可以用链表来存贮。同样的队列和栈也可以用数组和链表存贮,各有利弊。具体使用时,根据具体情况选择。
所以说,数组是一个更大的概念。使用数组,不但可以存储线性表,也可存储非线性结构的数据结构。比如堆、完全二叉树、乃至于其它类型的树、图等。
总结
顺序表与数组都是数据结构,只是描述角度不同。顺序表是从逻辑结构的角度来说的,它的每一个元素都只有一个前驱元素和一个后驱元素除了头和尾,逻辑结构还有队列,堆栈,树,图等。而数组是从物理存贮的角度来说的,顺序表用数组存贮也可以用链表来存贮。同样的队列也可以用数组和链表存贮,各有利弊。具体使用时,根据具体情况选择。
顺序表一般可以分为 :
1.静态顺序表 : 使用定长数组存储。
2.动态顺序表 : 使用动态开辟的数组存储。
SeqList.h 头文件:函数声明模块
#pragma once #include<stdio.h> #include<assert.h> //最初版本 //struct SeqList //{ // int data[100];//一个定长的数组 // struct SeqList* next;//指向下一个结点的地址的指针 //}; //进行优化 //1.这个结构体中的数据类型是int,这样就将数组的类型局限了,可能后面我们需要处理char、double或各种类型的数据 //为了数组类型的通用,我们可以将这个int进行类型重定义,后面如果有涉及到数据类型的修改,直接改动重定义部分的类型 //不涉及到结构体内数组元素类型的修改---便携性和通用性 //2.基于同样的道理,数组的大小100在结构体内局限性太强,为了方便数组大小实际应用过程中的调整 //可以将100用#define N,宏命令---便携性和通用性 //3.定义的结构体类型是 struct SeqList 这个类型名称太长,不方便我们后续写代码,可以对其进行类型重定义 //优化版本 #define N 100 typedef int SLDataType;//SL是SeqLsit的缩写,DataType表示数据类型 typedef struct SeqList { SLDataType data[N];//定长数组 //struct SeqList* next;//或者也可以用 SeqList* next; size_t size;//有效数据的个数 }SeqList; //初始化 void SeqListInit(SeqList* pList); //尾插 void SeqListPushBack(SeqList* pList, SLDataType x); //尾删 void SeqListPopBack(SeqList* pList); //打印 void SeqListPrint(SeqList* pList);
思考:顺序表为什么习惯用SeqList命名?有什么具体含义或者背景吗?
sequence 先后次序,顺序,连续 SeqList应该是Sequence + List 的缩写(方便理解和记忆)
SeqList.c 源文件,函数实现模块
#include"SeqList.h" //初始化 void SeqListInit(SeqList * pList) { assert(pList); pList->data[N] = 0; pList->size = 0; } //尾插 void SeqListPushBack(SeqList* pList, SLDataType x) { assert(pList); //1.首先考虑是否有空间给数据插入 if (pList->size == N) { printf("SeqList is full!\n"); } //2.有空间就往后面插入数据 else { int i = pList->size; pList->data[i] = x; pList->size++; } } //尾删 void SeqListPopBack(SeqList* pList) { assert(pList); //1.首先判断是否还存在可以删除的元素 if (pList->size == 0) { printf("SeqList is empty!\n"); printf("Delete date failure!\n"); } else { pList->size--; } } //打印 void SeqListPrint(SeqList* pList) { assert(pList); size_t i = 0; if (pList->size == 0) { printf("SeqList is empty!\n"); } else { for (i = 0; i < pList->size; i++) { printf(
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。