「数据结构」: 链表的实现

此次实现的数据结构仍为线性表,物理结构上采用链表结构,与顺序表相比有以下特点:

优点:不再有存储空间上的限制(主要取决了机器的存储能力,不会提前分配一定量的空间)

缺点:失去了随机存储特性,若只用简单的链表则查找、插入、删除都将占用O(K)的时间(K为操作位置)

使用C++语言实现。

代码如下:

  1 //linkList.h
  2 #ifndef __LINKLIST__
  3 #define __LINKLIST__
  4 #include <iostream>
  5 #include "excp.h"
  6 using namespace std;
  7 
  8 template<class T>
  9 class linkList;
 10 
 11 template<class T>
 12 class Node {
 13 public:
 14     Node(const T& newData) 
 15     {
 16         data = newData;
 17         next = NULL;
 18     }
 19     friend class linkList<T>;
 20 private:
 21     T data;
 22     Node<T> *next;
 23 };
 24 
 25 template<class T>
 26 class linkList{
 27 public:
 28     linkList(Node<T>* first){head = first;}
 29     linkList(){head = 0;}
 30     ~linkList();
 31     bool isEmpty() const {return head == 0;}
 32     int Length() const;
 33     bool findElement(int k, T& x) const;
 34     int searchElement(const T& x) const;
 35     linkList<T>& deleteElement(int k, T& x);
 36     linkList<T>& insertElement(int k, const T& x);
 37     void output(ostream& out) const;
 38 private:
 39     Node<T> *head;
 40 };
 41 
 42 //deconstructor
 43 template<class T>
 44 linkList<T>::~linkList()
 45 {
 46     Node<T> *next;
 47     while (head)
 48     {
 49         next = head->next;
 50         delete head;
 51         head = next;
 52     }
 53 }
 54 
 55 //get the length of the linkList
 56 template<class T>
 57 int linkList<T>::Length() const
 58 {
 59     Node<T> *cur = head;
 60     int len = 0;
 61     while (cur)
 62     {
 63         len++;
 64         cur = cur->next;
 65     }
 66     return len;
 67 }
 68 
 69 //find function, x carry the value of the index-k
 70 template<class T>
 71 bool linkList<T>::findElement(int k, T& x) const
 72 {
 73     if (k<1)
 74         return false;
 75     Node<T> *cur = head;
 76     int index = 1;
 77     while (index<k && cur)
 78     {
 79         index++;
 80         cur = cur->next;
 81     }
 82     if (cur)
 83     {
 84         x = cur->data;
 85         return true;
 86     }
 87     return false;
 88 }
 89 
 90 
 91 //search function
 92 template<class T>
 93 int linkList<T>::searchElement(const T& x) const
 94 {
 95     Node<T> *cur = head;
 96     int index = 1;
 97     while (cur)
 98     {
 99         if (x == cur->data)
100             return index;
101         index++;
102         cur = cur->next;
103     }
104     return 0;
105 }
106 
107 //call the override function later
108 template<class T>
109 void linkList<T>::output(ostream& out) const
110 {
111     Node<T> *cur = head;
112     while (cur)
113     {
114         out<<cur->data<<" ";
115         cur = cur->next;
116     }
117     out<<endl;
118 }
119 
120 //override
121 template<class T>
122 ostream& operator<<(ostream& out, const linkList<T>& x)
123 {
124     x.output(out);
125     return out;
126 }
127 
128 //delete operation
129 template<class T>
130 linkList<T>& linkList<T>::deleteElement(int k, T& x)
131 {
132     if (k<1 || !head)
133         throw OutOfBounds();
134     Node<T> *cur = head;
135     if (k == 1)
136     {
137         head = head->next;
138         x = cur->data;
139         delete cur;
140         return *this;
141     }
142     else
143     {
144          int index = 1;
145          //find the prior fo the kth node
146          while (index<k-1 && cur)
147          {
148              index++;
149              cur = cur->next;
150          }
151          if (!cur || !(cur->next))
152              throw OutOfBounds();
153          Node<T> *de = cur->next;
154          cur->next = de->next;
155          x = de->data;
156          delete de;
157          return *this;
158     }
159 }
160 
161 //insert operation
162 template<class T>
163 linkList<T>& linkList<T>::insertElement(int k, const T& x)
164 {
165     if (k<=0)
166         throw OutOfBounds();
167     Node<T> *newNode = new Node<T>(x);
168     if (k==1)
169     {
170         newNode->next = head;
171         head = newNode;
172     }
173     else
174     {
175         Node<T> *cur = head;
176         for (int index=1; index<k-1; index++)
177             cur = cur->next;
178         if (!cur)
179         {
180             delete newNode;
181             throw OutOfBounds();
182         }
183         newNode->next = cur->next;
184         cur->next = newNode;
185     }
186     return *this;
187 }
188 #endif
 1 //excep.h异常类
 2 #ifndef _EXCP_
 3 #define _EXCP_
 4 #include <new>
 5 using namespace std;
 6 
 7 class OutOfBounds {
 8 public:
 9     OutOfBounds(){}
10 };
11 
12 class FullMemery {
13 public:
14     FullMemery(){}
15 };
16 
17 void my_new_handler()
18 {
19     throw FullMemery();
20 }
21 
22 new_handler old_handler = set_new_handler(my_new_handler);
23 #endif
 1 //linkList.cpp测试主函数
 2 #include <iostream>
 3 #include "linkList.h"
 4 #include "excp.h"
 5 using namespace std;
 6 int main()
 7 {
 8     try{
 9         linkList<int> L;
10         cout<<"Length = "<<L.Length()<<endl;
11         cout<<"IsEmpty = "<<L.isEmpty()<<endl;
12         L.insertElement(1 ,2).insertElement(2, 6).insertElement(2, 3).
13         insertElement(3, 6);
14         cout<<"List is "<<L<<endl;
15         cout<<"IsEmpty ="<<L.isEmpty()<<endl;
16         int c;
17         L.findElement(1, c);
18         cout<<"First element is "<<c<<endl;
19         cout<<"Length = "<<L.Length()<<endl;
20         L.deleteElement(1, c).deleteElement(3, c);
21         cout<<"Delete element is "<<c<<endl;
22         cout<<"List is "<<L<<endl;
23     }
24     catch(...)
25     {
26         cerr<<"This is a error"<<endl;
27     }
28     return 0;
29 }

总结:

1、对于表的下标起始位置要统一,本次程序采用起始下标为1。

2、利用友元类的访问权限,但要适度。

3、注意处理内存垃圾。

原文地址:https://www.cnblogs.com/sangoly/p/3561649.html