《数据结构与算法》第二章 线性表

线性表



定义:

  由n个特性相同 数据元素(即可有很多数据项)构成的有限序列,同时相邻数据元素之间存在 序偶 关系。

  线性表中元素个数就是 表长

特点:

  ·存在唯一一个被称为 “第一个” 的数据元素(线性起点、起始结点);

  ·存在唯一一个被称为 “最后一个” 的数据元素(线性终点、终端结点);

  ·除第一个以外,结构中的每个数据元素均 只有一个前驱 

  ·除最后一个外,结构中的每个数据元素均 只有一个后继

顺序表示和实现



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

特点:

  ·数据元素在逻辑上相邻;

  ·数据元素也在物理次序上相邻(即在内存里也是连续存储的);

  ·可以理解为 数组 

存取方式:

  随机存取。

几个基本操作(伪码):

  ·类型定义:

1 #define MAXSIZE 100
2 typedef strut
3 {
4     ElemType *elem;
5     int length;
6 }SqList;

 

  ·初始化:

1 Status InitList(SqList &L)
2 {
3     L.elem = new ElemType[MAXSIZE];
4     if(!L.elem)    exit(OVERFLOW);
5     L.length = 0;
6     return OK;
7 }

  

  ·取值(时间复杂度O(1)):

1 Status GetElem(SqList L, int i, ElemType &e)
2 {
3     if(i < 1 || i > L.length) return ERROR;
4     e = L.elem[i - 1];
5     return OK;
6 }

  ·查找(时间复杂度O(n)):

1 int LocateElem(SqList L, ElemType e)
2 {
3     for(i = 0; i < L.length; i++)
4         if(L.elem[i] == e)    return i + 1;
5     return 0;
6 }

  ·插入(时间复杂度O(n)):

 1 Status ListInsert(SqList &L, int i, ElemType e)
 2 {
 3     if((i < 1) || (i > L.length + 1))    return ERROR;
 4     if(L.length == MAXSIZE)    return ERROR;
 5     for(j = L.length - 1; j >= i - 1; j--)
 6         L.elem[j + 1] = L.elem[j];
 7     L.elem[i - 1] = e;
 8     ++L.length;
 9     return OK;
10 }

  ·删除(时间复杂度O(n)):

1 Status ListDelete(SqList &L, int i)
2 {
3     if((i < 1) || (i > L.length))    return ERROR;
4     for(j = i; j <= L.length - 1; j++)
5         L.elem[j - 1] = L.elem[j];
6     -- L.length;
7     return OK;
8 }

链式表示和实现



线性表的链式表示指的是用一组任意的存储单元存储线性表的数据元素;

特点:

  ·存储单元可以连续也可以不连续;

  ·也就是以前学的链表。

存取方式:

  顺序存取(必须从头指针出发)。

几个基本操作(伪码):

  ·类型定义:

1 typedef struct LNode
2 {
3     ElemType data;
4     struct LNode *next;
5 }LNode, *LinkList;

  关于链表的一些特别的地方:

    ·data数据域next指针域

    ·LinkListLNode* 是等价的,但是习惯性的用 LinkList 定义单链表,用 LNode* 定义指向单链表中任意结点的指针变量;

    ·首元结点:链表中存储第一个数据元素的结点;

    ·头结点:可有可无(习惯上有),可以不存储信息,头指针连接,其指针域指向首元结点;

    ·头指针:指向链表中第一个结点的指针,即有头结点就指向头结点,无头结点就指向首元结点。

  ·初始化:

1 Status InitList(ListList &L)
2 {
3     L = new LNode;
4     L -> next = NULL;
5     return OK;
6 }

  ·取值:

 1 Status GetElem(LinkList l, int i, ElemType &e)
 2 {
 3     p = L -> next;
 4     j = 1;
 5     while(p && j < i)
 6     {
 7         p = p -> next;
 8         ++j;
 9     }
10     if(!p || j > i)    return EEOR;
11     e = p -> data;
12     return OK;
13 }

  ·查找:

1 LNode *LocateElem(LinkList L, ElemType e)
2 {
3     p = L -> next;
4     while(p && p -> data != e)
5         p = p -> next;
6     return p;
7 }

  ·插入:

 1 Status LinstInsert(LinkList &L, int i, ElemType e)
 2 {
 3     p = L;
 4     j = 0;
 5     while(p && (j < i - 1))
 6     {
 7         p = p -> next;
 8         ++j;
 9     }
10     if(!p || j > i - 1)    return ERROR;
11     s = new LNode;
12     s -> data = e;
13     s -> next = p -> next;
14     p -> next = s;
15     return OK;
16 }

  ·删除:

 1 Status ListDelete(LinkList &L, int i)
 2 {
 3     p = L;
 4     j = 0;
 5     whil((P ->next) && (j < i - 1))
 6     {
 7         p = p -> next;
 8         ++j;
 9     }
10     if(!(p -> next) || (j > i - 1))    return ERROR;
11     q = p -> next;
12     p -> next = q -> next;
13     deletd q;
14     return OK;
15 }

  ·前插法创建单链表:

 1 void CreateList_H(LinkList &L, int n)
 2 {
 3     L = new LNode;
 4     L -> next = NULL;
 5     for(i = 0; i < n; ++i)
 6     {
 7         p = new LNode;
 8         cin >> p -> data;
 9         p -> next = L -> next;
10         L -> next = p;
11     }
12 }

  ·后插法创建单链表:

 1 void CreateList_R(LinkList &L, int n)
 2 {
 3      L = new LNode;
 4      L -> next = NULL;
 5      r = L;
 6      for(i = 0; i < n; ++i)
 7      {
 8         p = new LNode;
 9         cin >> p -> data;
10         p -> next = NULL;
11         r -> next = p;
12         r =p;
13     }
14 }    

顺序表和单链表对比


  顺序表 链表
存储空间 预先分配,会导致空间闲置或溢出现象 动态分配,不会出现存储空间闲置或溢出现象
存储密度 不用为表示结点间的逻辑关系而增加额外的存储开销,存储密度等于1 需要借助指针来体现元素间的逻辑关系,存储密度小于1
存取元素 随机存取,按位置访问元素的时间复杂度为O(1) 顺序存取,按位置访问元素的时间复杂度为O(n)
插入、删除 平均移动约表中一般元素,时间复杂度为O(n) 不需要移动元素,确定插入、删除位置后,时间复杂度为O(1)
适用情况
表长变化不大,且能事先确定变化范围;

很少进行插入或者删除操作,经常按元素位置序号访问数据元素


长度变化较大

频繁进行插入或者删除操作

循环链表和双向链表



这两种不常用就不详细总结了。

循环链表:

  特点:表中最后一个结点的指针与指向头结点,整个链形成一个环。

  头指针:{ a1:          O(1) }

      { an:          O(n) }

  尾指针:{ a1: R -> next -> next   O(1) }

      { an: R                                 O(1) }

  由上可得,某些情况下循环链表中设立尾指针能简化操作。

双向链表:

  特点:一个结点有两个指针域,一个指向直接后继,一个指向直接前驱。

  克服了单链表的单向性,用空间换时间效率。

原文地址:https://www.cnblogs.com/wasi-991017/p/11574856.html

时间: 2024-10-11 21:43:38

《数据结构与算法》第二章 线性表的相关文章

数据结构期末复习第二章线性表

第二章:线性表 1.线性结构的基本特征答:线性结构是若干数据元素构成的有序(次序)集① 集合中必存在唯一的一个“第一元素”:② 集合中必存在唯一的一个 “最后元素”:③ 除第一元素之外,均有 唯一的前驱:④ 除最后元素之外,均有 唯一的后继. 2.线性表的顺序存储结构和链式存储结构分别是______.(  D )   A. 顺序存取的存储结构.顺序存取的存储结构  B. 顺序存取的存储结构.随机存取的存储结构   C. 随机存取的存储结构.随机存取的存储结构  D. 随机存取的存储结构.顺序存取

数据结构之第二章线性表之静态链式存储

1--特点:用一维数组来描述线性表,用游标代替指针指示节点在数组中的相对位置.不设“指针”类型的高级语言中适用链表结构. 2--线性表的静态链式存储结构 ////  静态单链表.h//  单链表的静态存储//// 6 //  Copyright (c) 2014年 dashuai. All rights reserved.// #ifndef SLIST_H#define SLIST_H#include <stdio.h>#include <stdlib.h> #define MA

第二章 线性表

2.1线性表类型定义 线性表描述:A=(a1,a2,...an);A为线性表的名称,ai为线性表 的数据元素. 线性表的离散定义:B=<A,R>,A包含n个结点(a1,a2,...an),R中只包含一个关系,即线性关系,R={(ai-1,ai)|i=1,2,....,n}, 一般的线性表的操作可以包含以下几种: * public linklist()  建立一个空的线性表. * public linklist(collection c)  将collection c中的数据依次建立一个线性表.

第二章——线性表

线性表 一.定义 线性表是最常用且最简单的一种数据结构. 简而言之,一个线性表是n个数据元素的有限的序列. 线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的 (注意,这句话只适用大部分线性表,而不是全部.比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储),但是把最后一个数据元素的尾指针指向了首位结点).by~百度百科 二.线性表的顺序表示和实现 1.顺序表示指的是用一组地址连续的储存单元依次储存线性表的数据元素. 通常用数组来

数据结构之第二章线性表之链式存储

1~~特点:逻辑上相邻的元素,他的物理位置不一定相邻,其实几乎是不像邻的.表中的元素只能顺序访问,插入,删除等操作只需修改指针而不需要移动元素,存储空间利用率高,表的容量可以动态变化.适合个数变化大的情况. 2--链式存储`的存储结构 typedef struct Node{ int data; struct Node *next; }NODE,*PNODE; 3~~线性表的基本操作 (1)线性表的的  插表头  建立算法 ” 插表头“方式得到的线性链表,元素存储的顺序和输入顺序相反,这与栈的特

数据结构之第二章线性表

1 线性表的顺序存储 (1)线性表的顺序存储特点:逻辑上相连的元素,物理位置也相连.可随机访问表中元素,表中的存储位置可以用一个简单的,直观的公式表示,但是插入和删除都要移动大量的元素,效率不高,适合元素个数变化不大的情况,此时,如数据元素按照一定的顺序存储,则称为顺序存储的有序表,简称为    静态表. (2)线性表的动态分配顺序存储结构 typedef struct{ Elemtype *elem; //存储空间起始地址 int length; //当前长度 int listsize; //

数据结构总结 第二章 线性表 抽象数据类型的具体实现

#include<stdio.h> #include<stdlib.h> #include<iostream> #define MAXSIZE 1000 #define ERROR 0 #define OK 1 using namespace std; typedef int Status; typedef int ElemType; /////////////线性表定义(顺序表)//////////////////////// typedef struct { Ele

数据结构之第二章线性表~~继续

(3)顺序表的查找 int locatlink(PNODE head,int e,int (*compare)(int ,int )) {//在head中查询第一个满足条件的元素的位置,若不存在,则返回-1 i: while(i<head.length&&!(*compare)(head.elem[i],e)) ++i; if(i<head.length) return i; else return -1; } 有序表的合并 void hebing(PNODE head1,PN

第二章 线性表2(链接表)

3.5.2 链接表接口 链接表可以看成是一组结点序列以及基于结点进行操作的线性结果的抽象,或则说是对链表的抽象. 链接表的接口: 1 package com.datastructure.chapter03.interfaces; 2 3 import com.datastructure.chapter03.exception.InvalidNodeException; 4 import com.datastructure.chapter03.exception.OutOfBoundaryExce