Ex8_10.h
上传用户:wuzhousb
上传日期:2022-07-12
资源大小:380k
文件大小:4k
源码类别:

书籍源码

开发平台:

Visual C++

  1. #include<iostream>
  2. using namespace std;
  3. //首先看结点组织,采用结点类加数据类
  4. class Object{//数据类为抽象类
  5. public:
  6. Object(){}
  7. virtual bool operator>(Object &)=0;//纯虚函数,参数必须为引用或指针
  8. virtual bool operator!=(Object &)=0;//纯虚函数,参数必须为引用或指针
  9. virtual void Print()=0;//纯虚函数
  10. virtual ~Object(){} //析构函数可为虚函数,构造函数不行
  11. };
  12. class Node{
  13. Object* info;     //数据域用指针指向数据类对象
  14. Node* link;     //指针域
  15. public:
  16. Node();           //生成头结点的构造函数
  17. ~Node();
  18. void InsertAfter(Node* P);                 //在当前结点后插入一个结点
  19. Node* RemoveAfter(); //删除当前结点的后继结点,返回该结点备用
  20. void Linkinfo(Object* obj);
  21. friend class List;
  22. //以List为友元类,List可直接访问Node的私有函数,与结构一样方便,但更安全
  23. };
  24. Node::Node(){info=NULL;link=NULL;}
  25. Node::~Node(){
  26. cout<<"删除结点类"<<'t';
  27. delete info; //释放数据域,自动调用数据域类析构函数,而数据域类对象是在main()中建立
  28. }
  29. void Node::InsertAfter(Node* p){
  30. p->link=link;
  31. link=p;
  32. }
  33. Node* Node::RemoveAfter(){
  34. Node* tempP=link;
  35. if(link==NULL) tempP=NULL;                 //已在链尾,后面无结点
  36. else link=tempP->link;
  37. return tempP;
  38. }
  39. void Node::Linkinfo(Object * obj){info=obj;}
  40. //再定义链表类,选择常用操作:包括建立有序链表、搜索遍历、插入、删除、取数据等
  41. class List{
  42. Node *head,*tail;//链表头指针和尾指针
  43. public:
  44. List();             //构造函数,生成头结点(空链表)
  45. ~List();                                   //析构函数
  46. void MakeEmpty();                              //清空一个链表,只余表头结点
  47. Node* Find(Object & obj);           //搜索数据域与定值相同的结点,返回该结点的地址
  48. int Length();                                //计算单链表长度
  49. void PrintList();                    //打印链表的数据域
  50.     void InsertFront(Node* p);      //可用来向前生成链表,在表头插入一个结点
  51. void InsertRear(Node* p);       //可用来向后生成链表,在表尾添加一个结点
  52. void InsertOrder(Node* p);  //按升序生成链表
  53. Node* CreatNode();//创建一个结点(孤立结点)
  54. Node* DeleteNode(Node* p);        //删除指定结点
  55. };
  56. List::List(){
  57. head=tail=new Node();
  58. }
  59. List::~List(){
  60. MakeEmpty();
  61. cout<<"删除头结点"<<'t';
  62. delete head;//自动调用结点类析构函数,因指针域空不再调数据域类析构函数
  63. }
  64. void List::MakeEmpty(){
  65. Node *tempP;
  66. while(head->link!=NULL){
  67. tempP=head->link;
  68. head->link=tempP->link;  //把头结点后的第一个节点从链中脱离
  69. delete tempP; //删除(释放)该结点,自动调用结点类析构函数,进一步自动调用数据域类析构函数
  70. }                 //千万不可在前面加 delete tempP->info; 来释放数据域类
  71. tail=head;  //表头指针与表尾指针均指向表头结点,表示空链
  72. }
  73. Node* List::Find(Object & obj){//对抽象类只能用“引用”
  74. Node* tempP=head->link;
  75. while(tempP!=NULL&&*tempP->info!=obj) tempP=tempP->link;
  76. return tempP;        //搜索成功返回该结点地址,不成功返回NULL
  77. }
  78. int List::Length(){
  79. Node* tempP=head->link;
  80. int count=0;
  81. while(tempP!=NULL){
  82. tempP=tempP->link;
  83. count++;
  84. }
  85. return count;
  86. }
  87. void List::PrintList(){
  88. Node* tempP=head->link;
  89. while(tempP!=NULL){
  90. tempP->info->Print();
  91. tempP=tempP->link;
  92. }
  93. cout<<endl;
  94. }
  95. void List::InsertFront(Node *p){
  96. p->link=head->link;
  97. head->link=p;
  98. if(tail==head) tail=p;
  99. }
  100. void List::InsertRear(Node *p){
  101. p->link=tail->link;
  102. tail->link=p;
  103. tail=p;
  104. }
  105. void List::InsertOrder(Node* p){
  106. Node *tempP=head->link,*tempQ=head;        //tempQ指向tempP前面的一个节点
  107. while(tempP!=NULL){
  108. if(*tempP->info>*p->info)break; //找第一个比插入结点大的结点,由tempP指向
  109. tempQ=tempP;
  110. tempP=tempP->link;
  111. }
  112. tempQ->InsertAfter(p); //插在tempP指向结点之前,tempQ之后
  113. if(tail==tempQ) tail=tempQ->link;
  114. }
  115. Node* List::CreatNode(){//建立新节点
  116. Node*tempP=new Node();
  117. return tempP;
  118. }
  119. Node* List::DeleteNode(Node* p){
  120. Node* tempP=head;
  121. while(tempP->link!=NULL&&tempP->link!=p) tempP=tempP->link;
  122. if(tempP->link==tail) tail=tempP;
  123. return tempP->RemoveAfter();       //本函数所用方法可省一个工作指针,与InsertOrder比较
  124. }