对于单链表,我们大多时候会用指针来实现(可参考基于指针实现的单链表)。现在我们就来看看怎么用数组来实现单链表。
1. 定义单链表中结点的数据结构
1 typedef int ElementType; 2 class NodeType 3 { 4 public: 5 ElementType data; 6 int next; 7 };
该结点包括了两个元素,其一是数据,另一个是指向下一个结点的“指针”(在这篇文章中实际上是指用于实现单链表的数组的下标。)
2. 定义一个的数组
1 const int CAPACITY = 1024; 2 NodeType node[CAPACITY];
在内存中该数组的结构如下图:
3. 定义指向单链表第1个结点的“指针”
1 int head;
4. 一个简单的单链表例子
我们假设单链表只有3个结点,并且3个结点从左到右分别位于数组node中第0、1、2位置,如下图:
head指向链表中的第1个结点。该结点存储于数组node的第0位置,data为111,next指向下一结点。其他以此类推。
需要注意的是链表的中最后一个结点(即上图中的第3个结点)的next被置为-1,表示不指向任何结点。
更为重要的是,这三个结点是可以位于数组node中的任一位置的,只要他们之间保持这种链接的关系。
5. 实际程序实现
在实际程序实现中,为了便于判断数组中哪一个元素已经被使用,我在原单链表的结点数据结构中又添加了一个判断位,如下:
1 typedef int ElementType; 2 class NodeType 3 { 4 public: 5 NodeType() { data = 0; next = NULL_VALUE; isFree = true; }; 6 ~NodeType() {}; 7 ElementType data; 8 int next; 9 bool isFree; // 标志位,为true表示该结点可用,反之不可用 10 };
其余的程序摘录如下:
1 #ifndef SINGLELINKEDLIST 2 #define SINGLELINKEDLIST 3 4 #include <iostream> 5 #include <cassert> 6 using namespace std; 7 8 const int CAPACITY = 1024; 9 const int NULL_VALUE = -1; 10 11 typedef int ElementType; 12 class NodeType 13 { 14 public: 15 NodeType() { data = 0; next = NULL_VALUE; isFree = true; }; 16 ~NodeType() {}; 17 ElementType data; 18 int next; 19 bool isFree; // 标志位,为true表示该结点可用,反之不可用 20 }; 21 22 class LinkedList 23 { 24 public: 25 LinkedList(); 26 virtual ~LinkedList(); 27 void initList(ElementType * arr, int len); 28 bool isEmpty(); 29 int findFreeNode(); 30 bool addNode(const int pos, const ElementType val); 31 bool deleteNode(const int pos); 32 void displayNodes(); 33 NodeType getNode(const int pos); 34 int getLenOfList(); 35 36 private: 37 NodeType node[CAPACITY]; 38 int head; 39 40 }; 41 42 43 #endif;