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 }