线性表---链式存储(双向链表)

Posted 2019-12-10-18ykx

tags:

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

本代码与上一代码单链表的极其相似,只是在插入删除操作中有所修改

注意:NULL是不可以有next结点和prior结点的(包括空表的表头,所以初始化链表只需head=NULL;一条语句),否则会导致调试过程异常终止。

 

  1 //链式存储---双向链表
  2 #include <iostream>
  3 using namespace std;
  4 //定义线性表类
  5 class List {
  6 private:
  7     //定义双向链表存储结构
  8     typedef struct LNode {
  9         int data;
 10         LNode *next;
 11         LNode *prior;
 12     };
 13     struct LNode *head;
 14 public:
 15     //构造函数(初始化)
 16     List() {
 17         head = NULL;
 18     }
 19     //析构函数
 20     ~List() {
 21         LNode *p;
 22         if (head == NULL) return;
 23         p = head;
 24         LNode *q;
 25         while (p != NULL) {
 26             p->prior = NULL;
 27             q = p->next;
 28             delete p;
 29             p = q;
 30         }
 31     }
 32     //插入
 33     void insertList(int a,int k);
 34     //删除
 35     void deleteList(int k);
 36     //查找    
 37     //按数字查找
 38     LNode *findList(int a) {
 39         LNode *p;
 40         p = head;
 41         while (p != NULL&&p->data!=a) {
 42             p = p->next;
 43         }
 44         if (p->data == a) return p;
 45         else return NULL;
 46     }
 47     //按序号查找
 48     LNode *FindList(int k) {
 49         //判断序号是否符合条件
 50         LNode *q;
 51         if (k<1 || k>getLength()) {
 52             cout << "查找元素位置不符合条件,查找失败" << endl;
 53             return NULL;
 54         }
 55         int i = 1;
 56         q = head;
 57         while (q != NULL && i < k) {
 58             q = q->next;
 59             i++;
 60         }
 61         if (i == k) return q;
 62         else {
 63             cout << "查找失败" << endl;
 64             return NULL;
 65         }
 66     }
 67     //求线性表长度
 68     int getLength();
 69     //判断表是否为空
 70     bool isEmpty();
 71     //清空线性表
 72     void clearList();
 73 };
 74 void List::insertList(int a,int k) {
 75     //插入位置是否符合条件
 76     int n = getLength();
 77     if (k<1 || k>(n+1)) {
 78         cout << "所输入的插入位置不满足条件,无法进行插入操作" << endl;
 79         return;
 80     }
 81     LNode *s, *p, *q;
 82     s = (LNode*)malloc(sizeof(LNode));
 83     if (k == 1) {
 84         s->data = a;
 85         s->next = head;
 86         if(n!=0) head->prior = s;
 87         head = s;
 88         return;
 89     }
 90     else if (k <= n) {
 91         k = k - 1;
 92         p = FindList(k);
 93         q = p->next;
 94         s->data = a;
 95         s->next = q;
 96         s->prior = p;
 97         p->next = s;
 98         q->prior = s;
 99         return;
100     }
101     else{//尾结点
102         p = FindList(k-1);
103         if (p == NULL) {
104             cout << "插入失败" << endl;
105             return;
106         }
107         s->data = a;
108         s->next = NULL;
109         s->prior = p;
110         p->next = s;
111         return;
112     }
113 }
114 void List::deleteList(int k) {
115     //判断k是否符合条件
116     if (k<1 || k>getLength()) {
117         cout << "所要删除结点位置不符合条件" << endl;
118         return;
119     }
120     LNode *p;
121     if (k == 1) {
122         p = head;
123         head = head->next;
124         head->prior = NULL;
125         free(p);
126         return;
127     }
128     LNode *s, *q;
129         p = FindList(k - 1);
130         s = p->next;
131         if (k < getLength()) {
132             q = s->next;
133             p->next = q;
134             q->prior = p;
135         }
136         else p->next = NULL;
137         free(s);
138         return;
139 }
140 int List::getLength() {
141     LNode *p;
142     int i = 0;
143     p = head;
144     while (p != NULL) {
145         p = p->next;
146         i++;
147     }
148     return i;
149 }
150 bool List::isEmpty() {
151     if (getLength() == 0) return true;
152     else
153         return false;
154 }
155 void List::clearList() {
156     //注意要释放每一个节点
157     LNode *p;
158     while (head != NULL) {
159         p = head;
160         head = head->next;
161         free(p);
162     }
163 }
164 
165 int main() {
166     List listA, listB;
167     int i;
168     cout << "开始进行插入操作" << endl;
169     for (i = 1; i <= 10; i++) {
170         listA.insertList(2 * i, i);
171     }
172     cout << "链表A插入操作结束" << endl;
173     for (i = 1; i <= 10; i++) {
174         listB.insertList(2 * i + 1, i);
175     }
176     cout << "链表B插入操作结束" << endl;
177     //依次输出两个线性表的元素
178     cout << "线性表A的元素如下" << endl;
179     for (i = 1; i <=listA.getLength(); i++) cout << listA.FindList(i)->data << "     ";
180     cout << endl;
181     cout << "线性表B的元素如下" << endl;
182     for (i = 1; i <= listB.getLength(); i++) cout << listB.FindList(i)->data << "      ";
183     cout << endl;
184     cout << "请输入要链表A删除的元素位置序号:";
185     int n;
186     cin >> n;
187     listA.deleteList(n);
188     cout << "删除节点后链表A内的元素依次为" << endl;
189     for (i = 1; i <= listA.getLength(); i++) cout << listA.FindList(i)->data << "      ";
190     cout << endl;
191     return 0;
192 }

调试结果如下:

技术图片

 

以上是关于线性表---链式存储(双向链表)的主要内容,如果未能解决你的问题,请参考以下文章

线性表的Java实现--链式存储(双向链表)

第三章 线性表---链式存储结构(双向链表)

数据结构第四篇——线性表的链式存储之双向链表

线性表的链式存储结构(链表)

双向链式线性表(模板实现)

数据结构与算法02--链表基础