线性表---顺序表&链表

一、线性表

    1、线性表中的元素是一对一的关系,除了第一个与最后一个元素之外其他数据元素都是首尾相连的。

如果是一对多就用树来表示,如果是多对多就用网状来表示。

    2、线性表的两种存储结构

  • 顺序表:用顺序结构保存数据,数据在内存中是连续的。
  • 链表:用链式存储结构保存数据,数据在内存中是不连续的。




二、顺序表

    1、顺序表:

  • 顺序表一般使用数组实现,顺序表的相关操作与数组相关,一般都是移动数组元素

    • 顺序表封装所需要的三个属性:

      • 存储空间的起始位置。数组date的存储位置就是线性表存储空间的存储位置。
      • 线性表的最大存储容量。数组长度MAXSIZE.
      • 线性表的的当前长度。length

注意:数组的长度与线性表的当前长度是不一样的。数组的长度是线性表的存储空间的总长度,一般初始化后不变。而线性表的当前长度是线性表中元素的个数,其大小是会改变的。

    2、顺序表的C++代码实现:模板类的代码

  •  1 #include<iostream>
     2 using namespace std;
     3
     4 const int MaxSize = 100;
     5 template <class DataType>
     6 class SeqList
     7 {
     8 public:
     9     SeqList(){length=0;}
    10     SeqList(DataType a[],int n);
    11     ~SeqList(){}
    12     int Length(){return length;}
    13     DataType Get(int i);
    14     int Locate(DataType x);
    15     void Insert(int i,DataType x);
    16     DataType Delete(int i);
    17     void PrintList();
    18 private:
    19     DataType data[MaxSize]; //顺序表使用数组实现
    20     int length;             //存储顺序表的长度
    21 };
    22
    23 template <class DataType>
    24 SeqList<DataType>::SeqList(DataType a[],int n)
    25 {
    26     if(n>MaxSize) throw "wrong parameter";
    27     for(int i=0;i<n;i++)
    28         data[i]=a[i];
    29     length=n;
    30 }
    31
    32 template <class DataType>
    33 DataType SeqList<DataType>::Get(int i)
    34 {
    35     if(i<1 && i>length) throw "wrong Location";
    36     else return data[i-1];
    37 }
    38
    39 template <class DataType>
    40 int SeqList<DataType>::Locate(DataType x)
    41 {
    42     for(int i=0;i<length;i++)
    43         if(data[i]==x) return i+1;
    44     return 0;
    45 }
    46
    47 template <class DataType>
    48 void SeqList<DataType>::Insert(int i,DataType x)//插入过程中应注意元素移动的方向必须从最后一个元素开始移动,如果表满了发生上溢出,如果插入位置不合理,则引发位置异常。
    49 {
    50     if(length>=MaxSize) throw "Overflow";
    51     if(i<1 || i>length+1) throw "Location";
    52     for(int j=length;j>=i;j--)
    53         data[j]=data[j-1];
    54     data[i-1]=x;
    55     length++;
    56 }
    57
    58 template <class DataType>
    59 DataType SeqList<DataType>::Delete(int i)//注意算法中元素移动的方向,移动元素之前必须取出被删的元素,如果表为空则引发下溢出,如果删除位置不合理则是引发删除位置异常
    60 {
    61     int x;
    62     if(length==0) throw "Underflow";
    63     if(i<1 || i>length) throw "Location";
    64     x = data[i-1];
    65     for(int j=i;j<length;j++)
    66         data[j-1] = data[j];
    67     length--;
    68     return x;
    69 }
    70
    71 template <class DataType>
    72 void SeqList<DataType>::PrintList()
    73 {
    74     for(int i=0;i<length;i++)
    75         cout<<data[i]<<endl;
    76 }
    77
    78 int main()
    79 {
    80     SeqList<int> p;
    81     p.Insert(1,5);
    82     p.Insert(2,9);
    83     p.PrintList();
    84     p.Insert(2,3);
    85     cout<<p.Length()<<endl;
    86     p.PrintList();
    87     cout<<p.Get(3)<<endl;
    88     p.Delete(2);
    89     p.PrintList();
    90     return 0;
    91 } 

    3、顺序表存储的优缺点:

  • 优点:
  • 随机访问特性,按位查找时间复杂度为O(1),存储密度高
  • 逻辑上相邻的元素物理上也相邻,即在内存中存储是连续的
  • 无需为表中元素之间的逻辑关系而增加额外的存储空间。
  • 缺点:
  • 插入和删除需要移动大量元素
  • 当线性表长度长度变化较大时,难以确定存储空间的容量
  • 造成存储空间的碎片




三、链表

    1、为什么要使用链表:

  • 顺序表的长度是固定的,如果超出分配的长度就会造成溢出,如果存放的数据太少就会造成空间浪费。
  • 在插入元素和删除元素时(尤其是插入和删除的位置不在尾部时),会移动大量元素,造成性能和效率低下。
  • 使用链表可以很好的避免顺序表中出现的问题。

    2、链表在内存中的存储是不连续的,大小不固定。链表根据构造方式的不同可以分为

      • 单向链表
      • 单向循环链表
      • 双向链表
      • 双向循环链表

    3、链式存储的实现方式

  • template<typename DateType>
    struct Node
    {
    DateType date;//存储数据
    Node<DateType> *next;//存储下一个结点得到地址
    }

    4、单链表的模板类的C++代码实现:

  • 头指针:把指向第一个节点的指针称为头指针,每次访问链表时都可以从这个头指针依次遍历链表中的每个元素
  • 1 struct node firs;2 struct node *head=&first; 这个head指针就是头指针。
      • 头指针的意义在于:当访问链表时,总要知道链表存储在什么位置(从何处开始访问),由于链表的特性(next指针),知道了头指针那么整个链表的元素都能够被访问,所以头指针的存在是很必要的。
  • 单链表的结构:单链表的模板类的结构:
    • template<class DataType>
      class LinkList
      {
      public:
          LinkList();
          LinkList(DataType a[], int n);
          ~LinkList();
          int Length();
          DataType Get(int i);
          int Locate(DataType x);
          void Insert(int i, DataType x);
          DataType Delete(int i);
          void PrintList();
      private:
          Node<DataType> *first;
      };

      特点:用一组任意的存储单元存储线性表的数据元素,这组存储单元可以在内存中未被占用的任意位置

    • 顺序存储结构每个数据元素只需要一个存储位置就可以了,而在链式存储结构中,除了要存储数据信息外还要存储它的后继元素的存储地址
    • 单链表中即使知道节点位置也不能直接访问,需要从头指针开始逐个节点向下搜索,平均时间复杂度是O(n).
    • 删除操作时需要注意表尾的特殊情况,此时虽然被删节点不存在,但其前驱结点却存在。因此仅当被删节点的前驱结点存在且不是终端结点时,才能确定被删节点存在,时间复杂度为O(n).

  •   1 #include<iostream>
      2 using namespace std;
      3
      4 template<class DataType>
      5 struct Node
      6 {
      7     DataType data;
      8     Node<DataType> *next;
      9 };
     10
     11 template<class DataType>
     12 class LinkList
     13 {
     14 public:
     15     LinkList();
     16     LinkList(DataType a[], int n);
     17     ~LinkList();
     18     int Length();
     19     DataType Get(int i);
     20     int Locate(DataType x);
     21     void Insert(int i, DataType x);
     22     DataType Delete(int i);
     23     void PrintList();
     24 private:
     25     Node<DataType> *first;
     26 };
     27
     28 template<class DataType>
     29 LinkList<DataType>::LinkList()
     30 {
     31     first = new Node<DataType>;
     32     first->next = NULL;
     33 }
     34
     35 template<class DataType>
     36 LinkList<DataType>::LinkList(DataType a[], int n)
     37 {
     38     first = new Node<DataType>;
     39     first->next = NULL;
     40     for (int i = 0; i < n; i++)
     41     {
     42         Node<DataType> *s = new Node<DataType>;
     43         s->data = a[i];
     44         s->next = first->next;
     45         first->next = s;
     46     }
     47 }
     48
     49 template<class DataType>
     50 LinkList<DataType>::~LinkList()
     51 {
     52     while (first != NULL)
     53     {
     54         Node<DataType>* q = first;
     55         first = first->next;
     56         delete q;
     57     }
     58 }
     59
     60 template<class DataType>
     61 int LinkList<DataType>::Length()
     62 {
     63     Node<DataType>* p = first->next;
     64     int count = 0;
     65     while (p != NULL)
     66     {
     67         p = p->next;
     68         count++;
     69     }
     70     return count;
     71 }
     72
     73 template<class DataType>
     74 DataType LinkList<DataType>::Get(int i)
     75 {
     76     Node<DataType>* p = first->next;
     77     int count = 1;
     78     while (p != NULL && count<i)
     79     {
     80         p = p->next;
     81         count++;
     82     }
     83     if (p == NULL) throw "Location";
     84     else return p->data;
     85 }
     86
     87 template<class DataType>
     88 int LinkList<DataType>::Locate(DataType x)
     89 {
     90     Node<DataType> *p = first->next;
     91     int count = 1;
     92     while (p != NULL)
     93     {
     94         if (p->data == x) return count;
     95         p = p->next;
     96         count++;
     97     }
     98     return 0;
     99 }
    100
    101 template<class DataType>
    102 void LinkList<DataType>::Insert(int i, DataType x)
    103 {
    104     Node<DataType> *p = first;
    105     int count = 0;
    106     while (p != NULL && count<i - 1)
    107     {
    108         p = p->next;
    109         count++;
    110     }
    111     if (p == NULL) throw "Location";
    112     else {
    113         Node<DataType> *s = new Node<DataType>;
    114         s->data = x;
    115         s->next = p->next;
    116         p->next = s;
    117     }
    118 }
    119
    120 template<class DataType>
    121 DataType LinkList<DataType>::Delete(int i)
    122 {
    123     Node<DataType> *p = first;
    124     int count = 0;
    125     while (p != NULL && count<i - 1)
    126     {
    127         p = p->next;
    128         count++;
    129     }
    130     if (p == NULL || p->next == NULL) throw "Location";
    131     else {
    132         Node<DataType> *q = p->next;
    133         int x = q->data;
    134         p->next = q->next;
    135         return x;
    136     }
    137 }
    138
    139 template<class DataType>
    140 void LinkList<DataType>::PrintList()
    141 {
    142     Node<DataType> *p = first->next;
    143     while (p != NULL)
    144     {
    145         cout << p->data << endl;
    146         p = p->next;
    147     }
    148 }
    149
    150 int main()
    151 {
    152     LinkList<int> p;
    153     p.Insert(1, 6);
    154     p.Insert(2, 9);
    155     p.PrintList();
    156     p.Insert(2, 3);
    157     p.PrintList();
    158     cout << p.Get(2) << endl;
    159     cout << p.Locate(9) << endl;
    160     cout << p.Length() << endl;
    161     p.Delete(1);
    162     p.PrintList();
    163     return 0;
    164 }
  • 链表存储的优缺点:
      • 优点:
      • 插入删除不需要移动其他元素,只需要改变指针。
      • 链表各个结点在内存中的存储空间不要求连续,空间利用率高
      • 缺点:查找需要遍历操作,比较麻烦。




四、其他线性表

    1、单向循环链表

    2、双向链表

    3、双向循环链表

原文地址:https://www.cnblogs.com/southcyy/p/10326139.html

时间: 2024-10-11 01:07:08

线性表---顺序表&链表的相关文章

线性表——顺序表与单链表学习小结

线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列. 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表.链表.栈.队列.字符串... 线性表在逻辑上是线性结构,也就说是连续的一条直线.但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储. 顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储.在数组上完成数据的增删查改. 链表 链表是一种物理存储结构上非连续.非顺序的存储结构,数据

java实现数据结构-线性表-顺序表,实现插入,查找,删除,合并功能

package 顺序表; import java.util.ArrayList; import java.util.Scanner; public class OrderList { /** * @param args * @author 刘雁冰 * @2015-1-31 21:00 */ /* * (以下所谓"位置"不是从0开始的数组下标表示法,而是从1开始的表示法.) * (如12,13,14,15,16数据中,位置2上的数据即是13) * * 利用JAVA实现数据结构-线性表-顺

线性表&gt;&gt;顺序表---&gt;逆置所有元素

1 /*顺序表中所有的元素逆置 2 * 3 */ 4 #include <iostream.h> 5 using namespace std; 6 7 int main(){ 8 void reverse_arr(int arr[],int n); 9 int a[]={0,1,2,3,4,5,6,7}; 10 int n=7; 11 reverse_arr(a,n); 12 for(int i=0;i<=n;i++){ 13 cout << a[i] << &q

C++数据结构与算法_2_线性表 --顺序表的应用示例

h2.western { font-family: "Liberation Sans",sans-serif; font-size: 16pt; }h2.cjk { font-family: "微软雅黑"; font-size: 16pt; }h2.ctl { font-family: "AR PL UMing CN"; font-size: 16pt; }h1 { margin-bottom: 0.21cm; }h1.western { fon

C++数据结构与算法_1_线性表 --顺序表的实现与分析

顺序表的实现与分析 引 --线性表的抽象基类: template <typename T> class LinearList { public: LinearList(); ~LinearList(); virtual int Size() const = 0; //返回线性表所能够存储的最大长度 virtual int Length() const = 0; //当前线性表的长度 virtual int Search(T &x) const = 0; virtual int Loca

线性表-顺序表、链表类模板的实现(数据结构基础 第2周)

学习完课程后,自己用C++实现了简单的顺序表和链表,并用约瑟夫问题做了测试,不保证完全正确. 其中有一点需要注意一下:C++中类模板声明头文件和实现头文件不可以分离到.h和.cpp中,否则无法正常编译,详见:https://www.zhihu.com/question/20630104 源码 1.顺序表 //seqlist.h #pragma once #include <iostream> using namespace std; template <class T> class

数据结构和算法-数据结构-线性结构-顺序表 链表和哈希表

####################################################### """ # 线性表是最基本的数据结构之一,在实际程序中应用非常广泛,它还经常被用作更复杂的数据结构的实现基础. # 根据线性表的实际存储方式,分为两种实现模型: # 顺序表, # 链表, # 下面分别进行研究, """ ####################################################### &qu

数据结构之 线性表--顺序创建链表

数据结构实验之链表一:顺序建立链表 Time Limit: 1000MS Memory limit: 65536K 题目描述 输入N个整数,按照输入的顺序建立单链表存储,并遍历所建立的单链表,输出这些数据. 输入 第一行输入整数的个数N: 第二行依次输入每个整数. 输出 输出这组整数. 示例输入 8 12 56 4 6 55 15 33 62 示例输出 12 56 4 6 55 15 33 62 写的时候,定义一个结构体变量就要为它申请空间,不然程序会运行时出问题 ! #include <ios

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

总括: 线性表是一种最简单的数据结构,线性表的主要操作特点是可以在任意位置插入和删除一个数据元素. 线性表可以用顺序存储结构和链式存储结构存储,用顺序存储结构实现的线性表称为顺序表,用链式存储结构实现线性表称为链表. 1,线性表概述: 线性表:线性表是一种可以在任意位置进行插入和删除数据元素操作的,有n个(n>=0)个相同类型数据元素a0,a1,. . .an组成的线性结构. 线性表抽象数据类型:抽象数据类型是指一个逻辑概念上的类型和这个类型上的操作集合:因此,线性表的抽象数据类型主要包括两个方