数据结构-线性表-实验

  题目:建立一个循环单链表,其节点有 prior,data 和 next 三个域,其中 data 为数据域,存放元素的有效信息,next 域为指针域,指向后继节点,prior 为指针域,它的 值为 NULL。编写一个算法将此表改为循环双链表。

  算法描述:首先你需要有一个循环单链表,但是他的节点有两个指针域一个数据域。在初始化的时候就让所有的prior指向nullptr,让这个指针失去作用,之后的操作和普通的循环单链表是一样的。在循环单链表建立之后,我们在对所有节点的prior指针进行指向就可以完成循环双链表的改造。

  已建有一个单循环链表(带头结点),first 指向头结点。设 立两个工作指针 p 和 q,分别指向头结点和第 1 个结点;执行 q->prior=p;,建立第 1 个结点的前驱指针,如图 1-4 所示;同步移动工作指针 p 和 q 分别指向下一个结点, 如图 1-5 所示,建立 q 指向结点的前驱,直到 q==first 为止,再将头结点的前驱设为 最后一个结点。

LinkList.h

 1 #ifndef LinkList_H      //避免重复包含LinkList.h头文件
 2 #define LinkList_H
 3  
 4 // 定义链表结点 
 5 template <typename DataType> struct Node
 6 {
 7     DataType data;
 8     struct Node<DataType> *prior, *next;     
 9 };
10 
11 //定义链表 
12 template <typename DataType> class LinkList
13 {
14 public:    
15     LinkList();                            // 只有头结点的空链表
16     LinkList(DataType a[], int n);         // 建立n个元素的单链表
17     ~LinkList();                        // 析构函数 
18     void printlist();                    // 用尾指针遍历链表 
19     void arithmetic();                    // 法将此表改为循环双链表
20 private:
21     struct Node<DataType> *first;        // 头指针 
22 };
23 #endif

LinkList.cpp

 1 # include <iostream>
 2 # include <cstdlib>
 3 using namespace std;
 4 # include "LinkList.h"
 5 
 6 // 无参数构造函数 
 7 template <typename DataType> LinkList<DataType>::LinkList()
 8 {
 9     first = new Node<DataType>;
10     first->next = first;
11     first->prior = NULL;
12 }
13 
14 // 有参数构造函数 
15 template <typename DataType> LinkList <DataType>::LinkList(DataType a[], int n)
16 {
17     first = new Node<DataType>;
18     first->next = first;
19     first->prior = NULL;
20     for (int i = 0; i <n; i++)
21     {
22         Node<DataType> *s = NULL;
23         s = new Node<DataType>;
24         s->data = a[i];
25         s->prior = NULL;
26         s->next = first->next;
27         first->next = s; 
28     }    
29 }
30 
31 // 析构函数
32 template <typename DataType> LinkList<DataType>::~LinkList()
33 {
34     Node<DataType> *p = first;            // 建立工作指针
35     while (first != NULL)
36     {
37         first = first->next;
38         delete p;
39         p = first;
40     }
41 }
42 
43 // 用尾指针遍历链表 
44 template <typename DataType> void LinkList<DataType>::printlist() 
45 {
46     Node<DataType> *p = first->next;            // 建立工作指针
47     cout<<"利用后继指针遍历链表:"<<endl<<'\t'; 
48     while (p != first)                            // 当工作指针p指向头结点时遍历结束 
49     {
50         cout<<p->data<<"\t";
51         p = p->next;
52     }
53     cout<<endl;
54 }
55 
56 // 法将此表改为循环双链表
57 template <typename DataType> void LinkList<DataType>::arithmetic()
58 {
59     if (first->next == first) throw "这个链表只有头结点";
60     
61     Node<DataType> *p = first, *q = p->next;        // 建立工作指针,p指向头结点,q指向首节点 
62 
63     while (q != first)
64     {    
65         q->prior = p;
66         p = p->next;
67         q = q->next;
68     }
69     
70     
71     
72     q->prior = p;                                        // 当q指向头结点,p指向尾结点,将头结点的前驱指向尾结点 
73     cout<<"已经将链表改造成循环双链表!"<<endl;
74     cout<<"利用前驱指针遍历链表:"<<endl<<'\t';
75     while (p != first)                            // 当工作指针p指向头结点时遍历结束 
76     {
77         cout<<p->data<<"\t";
78         p = p->prior;
79     }
80     cout<<"\n\n\n";
81     
82 }

LinkList_main.cpp

 1 # include "LinkList.cpp"
 2 
 3 int main(void)
 4 {
 5     int A[7] = {1, 2, 3, 4, 5, 6, 7};
 6     int B[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
 7     
 8     LinkList<int> L1(A, 7);                // 使用有参构造函数创建链表 
 9     L1.printlist();
10     L1.arithmetic();
11     
12 
13     LinkList<int> L2(B,10);                // 使用有参构造函数创建链表     
14     L2.printlist();
15     L2.arithmetic();
16     
17     system("pause");
18     return 0;
19 }

猜你喜欢

转载自www.cnblogs.com/Takeshi-Gian/p/12942473.html