1 #include<iostream>
2 #include<cstring>
3 #include<string>
4 using namespace std;
5
6 class Object { //抽象结点数据类,用于派生实际结点数据类
7 public :
8 Object() { //可省略---因为有默认构造函数,且正好它什么都不做
9 }
10 virtual int IsEqual(Object &) = 0; //实现两个结点数据的比较
11 virtual float Data() = 0; //得到实际结点数据类的数据
12 virtual void Show() = 0; //输出一个结点上的数据
13 virtual ~Object() {} //虚析函数
14 };
15
16 class Node { //结点类
17 Object *Info; //指向结点的数据域
18 Node *Next; //指向下一个结点
19 public :
20 Node() {
21 Info = nullptr; Next = nullptr; //默认构造函数
22 }
23 Node(Node &node) {
24 Info = node.Info; Next = node.Next; //复制构造函数
25 }
26 void FillInfo(Object *obj) { //使Info指向数据域,实参为实际结点数据类,
27 Info = obj;
28 }
29 friend class List; //声明友元类
30 };
31
32 //定义单向链表类
33 class List {
34 Node *Head; //链表首指针
35 public :
36 List() {
37 Head = nullptr;
38 }
39 ~List() { //析构函数
40 DeleteList();
41 }
42 void AddNode(Node *node); //插入链表
43 Node* Insert(Node *node); //升序链表
44 Node* LookUp(Object &obj); //查找链表
45 Node* DeleteNode(Node *node); //删除指定链表
46 void ShowList(); //输出整条链表
47 void DeleteList(); //删除整条链表
48 };
49
50 void List::AddNode(Node *node) //有序添加结点--调用Insert函数
51 {
52 if (Head == nullptr)
53 {
54 Head = node; node->Next = nullptr;
55 }
56 else
57 {
58 node = Insert(node);
59 }
60 }
61
62 Node* List::Insert (Node *node)
63 {
64 if (node->Info->Data() < Head->Info->Data())
65 {
66 node->Next = Head; Head = node;
67 return node;
68 }
69 Node *p1, *p2;
70 p2 = p1 = Head;
71 while (p2->Next && p2->Info->Data() < node->Info->Data())
72 {
73 p1 = p2; p2 = p2->Next;
74 }
75 if (node->Info->Data() > p2->Info->Data())
76 {
77 p2->Next = node; node->Next = nullptr;
78 }
79 else
80 {
81 p1->Next = node; node->Next = p2;
82 }
83 return Head;
84 }
85
86 Node* List::DeleteNode(Node *node)
87 {
88 if (node == Head)
89 Head = Head->Next;
90 else
91 {
92 Node *p1, *p2;
93 p2 = p1 = Head;
94 while (p2->Next && p2 != node)
95 {
96 p1 = p2; p2 = p2->Next;
97 }
98 if (p2 == node)
99 p1->Next = p2->Next;
100 }
101 return node;
102 }
103
104 Node* List::LookUp(Object &obj)
105 {
106 Node *p = Head;
107 while (p)
108 {
109 if (p->Info->IsEqual(obj)) return p;
110 p = p->Next;
111 }
112 return nullptr;
113 }
114
115 void List::ShowList()
116 {
117 Node *p = Head;
118 while (p)
119 {
120 p->Info->Show(); p = p->Next;
121 }
122 }
123
124 void List::DeleteList()
125 {
126 Node *p;
127 while (Head)
128 {
129 p = Head;
130 delete p->Info; //delete Object类类型的指针时 调用的是指针指向的派生类的析构函数
131 Head = p->Next;
132 delete p;
133 }
134 }
135 //员工类
136 class Staff : public Object{ //实际结点数据类:由抽象类Object类派生出
137 char *Name;
138 string Address;
139 float Salary;
140 public :
141 Staff(char *name = "",string address = "",float salary = 0.0f) {
142 Name = new char[strlen(name)+1];
143 strcpy(Name,name);
144 Address = address;
145 Salary = salary;
146 }
147 void SetData(char *name = "",string address = "",float salary = 0.0f) {
148 Name = new char[strlen(name)+1];
149 strcpy(Name,name);
150 Address = address;
151 Salary = salary;
152 }
153 virtual float Data() {
154 return Salary;
155 }
156 int IsEqual(Object &obj)
157 {
158 Staff t = (Staff&) obj;
159 return Salary == t.Salary;
160 }
161 void Show()
162 {
163 cout << "姓名: " << Name << ",地址: " << Address << ",工资: " << Salary << endl;
164 }
165 ~Staff() {
166 delete []Name;
167 }
168 };
169
170 int main(void)
171 {
172 int n;
173 char name[9];
174 string address;
175 float salary;
176 Staff *p;
177 Node *pn, *pt;
178 List list;
179
180 cout << "input the num of staff : ";
181 cin >> n;
182 for (int i = 0; i < n; i++)
183 {
184 pn = new Node;
185 cout << "输入姓名、地址、工资: ";
186 cin >> name >> address >> salary;
187 // p.SetData(name,address,salary);
188 p = new Staff(name,address,salary);
189 pn->FillInfo(p);
190 list.AddNode(pn);
191 }
192 list.ShowList(); //显示当前链表数据
193 cout << endl;
194 // pn = list.LookUp(*p);
195 Staff da; //声明派生类类型对象
196 cout << "输入新增成员的薪水(新成员已经确定): ";
197 cin >> salary;
198 da.SetData("sandy","美国",salary); //修改派生类对象的数据
199 pn = new Node;
200 pn->FillInfo(&da); //将结点数据指针指向派生的数据---检测fillinfo是否会指向Staff类普通对象
201 list.AddNode(pn); //将新结点(升序)添加到链表中
202 list.ShowList();
203 cout << endl;
204
205 if (pn) pn = list.LookUp(da);//在链表中寻找指定数据(派生类对象),找到返回该结点,否则返回NULL
206 if (pn)
207 pt = list.DeleteNode(pn);//删除指定的链表---返回值为该结点
208 list.ShowList();
209 cout << endl;
210 list.DeleteList();
211 return 0;
212
213 }