数据结构一:线性表

Posted Hot_Destiny

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构一:线性表相关的知识,希望对你有一定的参考价值。

线性表是最常用也是最简单的数据结构,几种常用的线性表的类模板C++描述描述如下:

1.顺序表

顺序表是将所有元素按逻辑顺序存储在一组地址连续的存储空间中的简单数据结构:

 1 const int MAXSIZE = 1000;
 2 template<class T>
 3 class SeqList
 4 {
 5 public:
 6     SeqList(){ lenght = 0; }           // 无参构造函数
 7     SeqList(const T a[], int n);       // 带参构造函数,并用数组初始化
 8 
 9     int GetLenght() const{ return lenght; }// 返回顺序表长度
10     void PrintList()const;                 // 依次遍历顺序表各个数据元素
11     void Insert(int i, T x);               // 指定位置插入数据元素
12     T Delete(int i);                       // 删除指定位置的数据元素,并返回这个元素
13     T Get(int i) const;                    // 获取指定位置的数据元素
14     int Locate(T x) const;                 // 查找指定元素并返回其位置
15 private:
16     T data[MAXSIZE];                       // 存储顺序表中各个数据元素
17     int lenght;                            // 顺序表长度
18 };
19 
20 
21 // 构造函数
22 template<class T>
23 SeqList<T>::SeqList(const T a[], int n)
24 {
25     if (n > MAXSIZE)
26         throw"数组长度超出顺序表最大长度";
27     for (int i = 0; i < n; i++)
28         data[i] = a[i];
29     lenght = n;
30 }
31 
32 // 遍历顺序表
33 template<class T>
34 void SeqList<T>::PrintList()const
35 {
36     std::cout << "顺序表中元素依次如下所示:" << endl;
37     for (int i = 0; i < lenght; i++)
38         std::cout << data[i] << " ";
39     std::cout << std::endl;
40 }
41 
42 // 插入元素
43 template<class T>
44 void SeqList<T>::Insert(int i, T x)
45 {
46     if (lenght >= MAXSIZE)
47         throw"上溢异常";
48     if (i<1 || i>lenght)
49         throw"插入位置不合法";
50     for (int j = lenght; j >= i; j--)
51         data[j] = data[j - 1];
52     data[i - 1] = x;
53     lenght++;
54 }
55 
56 // 删除元素
57 template<class T>
58 T SeqList<T>::Delete(int i)
59 {
60     if (0 == lenght)
61         throw"下溢异常";
62     if (i<1 || i>lenght)
63         throw"删除位置不合法";
64     T X = data[i - 1];
65     for (int j = i; j < lenght; j++)
66         data[j - 1] = data[j];
67     lenght--;
68     return X;
69 }
70 
71 // 查找元素
72 template<class T>
73 T SeqList<T>::Get(int i)const
74 {
75     if (i<1 || i>lenght)
76         throw"查找位置不合法";
77 
78     return data[i - 1];
79 }
80 
81 // 定位元素
82 template<class T>
83 int SeqList<T>::Locate(T x)const
84 {
85     for (int i = 0; i < lenght; i++)
86     {
87         if (x == data[i])
88             return i + 1;
89     }
90     
91     throw"查找的元素不存在顺序表中";
92     return 0;
93 }
View Code

2.单链表

单链表与顺序表不同的地方是存放的元素地址是零散的,可能连续也可能不连续,保证彼此之间的联系,因此,在存储元素的时候需要存储下一个元素的地址:

  1 template<class T>
  2 struct Node
  3 {
  4     T data;
  5     Node*next;
  6 };
  7 
  8 
  9 template<class T>
 10 class LinkList
 11 {
 12 public:
 13     LinkList(){ front = new Node<T>; front->next = NULL; }// 无参构造函数
 14     LinkList(T a[], int n);                               // 带参构造函数,用数组初始化链表 
 15     ~LinkList();                                          // 析构函数
 16     void PrintList()const;                                // 依次遍历链表元素
 17     int GetLenght()const;                                 // 返回链表长度
 18     Node<T>*Get(int i)const;                              // 返回指定位置的数据元素
 19     int Locate(T x)const;                                 // 查找指定元素,并返回其位置
 20     void Insert(int i, T x);                              // 指定位置插入指定元素
 21     T Delete(int i);                                      // 删除指定位置的元素
 22 private:
 23     Node<T>*front;                                        // 头指针
 24 };
 25 
 26 
 27  // 头插法
 28 template<class T>
 29 LinkList<T>::LinkList(T a[], int n)
 30 {
 31     front = new Node<T>;             
 32     front->next = NULL;                                   // 构造空链表
 33     for (int i = n - 1; i => 0;i--)
 34     {
 35         Node<T>*s = new Node<T>;                          // 建立新结点
 36         s->data = a[i];                                   // 将值写入结点数据域
 37         s->next = front->next;                            // 修改新节点指针域
 38         front->next = s;                                  // 修改头结点指针域
 39     }
 40 }
 41 
 42 // 尾插法
 43 template<class T>
 44 LinkList<T>::LinkList(T a[], int n)
 45 {
 46     front = new Node<T>;
 47     Node<T>*r = front;
 48     for (int i = 0; i < n;i++)
 49     {
 50         Node<T>*s = new Node<T>;           // 建立新结点
 51         s->data = a[i];                    // 将值写入新结点数据域
 52         r->next = s;                       // 将新结点加入链表
 53         r = s;                             // 修改尾指针
 54     }
 55     r->next = NULL;
 56 }
 57 
 58 template<class T>
 59 LinkList<T>::~LinkList()
 60 {
 61     Node<T>*p = front;                    // 初始化工作指针
 62     while (p)
 63     {
 64         front = p;                        // 暂存工作指针  
 65         p = p->next;                      // 移动工作指针到下一个结点
 66         delete front;                     // 释放结点
 67     }
 68 }
 69 
 70 template<class T>
 71 Node<T>*LinkList<T>::Get(int i)const
 72 {
 73     Node<T>*p = front->next;              // 初始化工作指针
 74     int j = 1;                            // 初始化计数器
 75     while (p&&j!=i)                       
 76     {
 77         p = p->next;                      // 移动工作指针
 78         j++;                              // 计数器递增
 79     }
 80     return p;                             // 返回查找结果
 81 }
 82 
 83 template<class T>
 84 int LinkList<T>::Locate(T x)const
 85 {
 86     Node<T>*p = front->next;              // 初始化工作指针
 87     int j = 1;                            // 初始化计数器
 88     while (p)
 89     {
 90         if (x == p->data)                 // 找到指定元素就返回位置
 91             return j;                     
 92         p = p->next;                      // 移动工作指针
 93         j++;                              // 递增计时器
 94     }
 95     return -1;                            // 若找不到,返回-1
 96 }
 97 
 98 template<class T>
 99 void LinkList<T>::Insert(int i, T x)
100 {
101     Node<T>*p = front;                    // 初始化工作指针
102 
103     if (i != 1)
104         p = Get(i - 1);                   // 返回插入位置前一个元素的位置
105     if (p)
106     {
107         Node<T>*s = new Node<T>;
108         s->data = x;                      // 插入元素数据区域赋值
109         s->next = p->next;                // 插入元素指针区域赋值
110         p->next = s;                      // 插入元素接入链表
111     }
112     else
113         throw"插入位置错误!";
114 }
115 
116 template<class T>
117 T LinkList<T>::Delete(int i)
118 {
119     Node<T>*p = front;                 // 初始化工作指针
120     if (i != 1)
121         p = Get(i - 1);                // 获取第i-1个元素的地址
122     Node<T>*q = p->next;               // 获取第i个元素的地址
123     p->next = q->next;                 // 将第i+1个元素与第i个元素链接
124     T x = q->data;                     // 保存被删除元素
125     delete q;                          // 删除指定位置元素
126     return x;                          // 返回被删除的元素
127 }
128 
129 template<class T>
130 void LinkList<T>::PrintList()const
131 {
132     Node<T>*p = front->next;
133     std::cout << "链表元素依次为:";
134     while (p)
135     {
136         std::cout << (p->data) << " ";
137         p = p->next;
138     }
139     std::cout << std::endl;
140 }
141 
142 template<class T>
143 int LinkList<T>::GetLenght()const
144 {
145     Node<T>*p = front->next;
146     int j = 1;
147     while (p)
148     {
149         p = p->next;
150         j++;
151     }
152 
153     return j;
154 }
View Code

3.单循环链表

单循环链表与单链表没有太大区别,为了访问链表的首尾段,将之前的头指针换成了尾指针,尾指针指向链表尾部,尾指针指针域指向链表第一个元素:

  1 template<class T>
  2 struct Node
  3 {
  4     T data;     // 数据域
  5     Node*next;  // 指针域
  6 }
  7 
  8 template<class T>
  9 class CLinkList
 10 {
 11 public:
 12     CLinkList(){ rear = new Node<T>; rear->next = rear; } // 无参构造函数
 13     CLinkList(T a[], int n);                              // 用数组初始化单循环链表
 14 
 15     ~CLinkList();                                         // 析构函数
 16     int GetLenght()const;                                 // 返回链表长度
 17     Node<T>*Get(int i)const;                              // 返回指定位置元素数据
 18     int Locate(T x)const;                                 // 查找指定元素,并返回其位置
 19     void Insert(int i, T x);                              // 指定位置插入元素
 20     T Delete(int i);                                      // 删除指定位置的元素,并返回其值
 21     void PrintList()const;                                // 依次遍历链表元素
 22     void Connect(CLinkList<T>&B);                         // 将链表B链接到表尾
 23 
 24 private:
 25     Node<T>*rear;                                         // 尾指针(指向最后一个元素)
 26 };
 27 
 28 
 29 template<class T>
 30 CLinkList<T>::CLinkList(T a[], int n)   // 尾插法
 31 {
 32     rear = new Node<T>;
 33     rear->next = rear;       // 初始化尾指针
 34     for (int i = 0; i < n; i++)
 35     {
 36         Node <T>*s = new Node <T>;
 37         s->data = a[i];      // 数据域赋值
 38         s->next = rear->next;// 新增结点指针指向头结点
 39         rear->next = s;      // 新增结点添加到链表中
 40         rear = s;            // 尾指针指向尾结点
 41     }
 42 }
 43 
 44 
 45 template<class T>
 46 void CLinkList<T>::PrintList()const
 47 {
 48     std::cout << "单循环链表各元素如下:";
 49     Node<T>*p = rear->next;              // 初始化工作指针指向头结点
 50     do
 51     {
 52         p = p->next;                     // 修改工作指针
 53         std::cout << p->data << " ";     // 打印
 54     } while (p != rear);
 55 
 56     std::cout << std::endl;
 57 }
 58 
 59 template<class T>
 60 CLinkList<T>::~CLinkList()
 61 {
 62     Node<T>*p = rear->next;         // 初始化工作指针
 63     Node<T>*q = rear->next;         // 初始化工作指针
 64     while (p!=rear)
 65     {
 66         q = p;
 67         p = p->next;
 68         delete q;
 69     }
 70     delete p;                      // 释放尾结点
 71 }
 72 
 73 
 74 template<class T>
 75 int CLinkList<T>::GetLenght()const
 76 {
 77     Node<T>*p = rear->next;         // 初始化工作指针
 78     int j = 0;                      // 元素计数器
 79     while (p != rear)
 80     {
 81         p = p->next;                // 移动工作指针
 82         j++;
 83     }
 84     return j;
 85 }
 86 
 87 template<class T>
 88 Node<T>*CLinkList<T>::Get(int i)const
 89 {
 90     Node<T>*p = rear->next;                   // 初始化工作指针
 91     int j = 0;                                // 计数器
 92     while ((p != rear) && (j != i))
 93     {
 94         p = p->next;                          // 移动工作指针
 95         j++;
 96     }
 97     return p;
 98 }
 99 
100 template<class T>
101 int CLinkList<T>::Locate(T x)const
102 {
103     Node<T>*p = rear->next;             // 初始化工作指针
104     int j = 0;                          // 计数器
105     while (p != rear)
106     {
107         if (p->data == x)
108             return j;
109         p = p->next;                   // 移动工作指针
110         j++;
111     }
112     return -1;
113 }
114 
115 template<class T>
116 T CLinkList<T>::Delete(int i)
117 {
118     Node<T>*P = rear;                  // 初始化工作指针
119     if (i != 1)
120         P = Get(i - 1);                // 获取第i-1个元素的地址
121     Node<T>*q = P->next;               // 获取第i个元素的地址
122     P->next = q->next;                 // 将第i+1个元素与第i个元素链接
123     T x = q->data;                     // 保存被删除元素
124     delete q;                          // 删除指定位置元素
125     return x;                          // 返回被删除的元素
126 }
127 
128 template<class T>
129 第02次作业-线性表

博客作业2---线性表

第02次作业-线性表

数据结构 线性表 用c语言

线性表

第02次作业-线性表