Node类头文件
#ifndef NODE_H_
#define NODE_H_
#include <iostream>
#include <string>
using namespace std;
class Node
{
friend ostream& operator<< (ostream&, const Node& );
friend class LinkList;
public:
Node(const string name = "None");
private:
string name;
Node* next;
};
#endif
Node类cpp
#include "Node.h"
using namespace std;
//重载<<运算符
ostream& operator<<(ostream& os, const Node& _node)
{
os << "Name:" << _node.name;
return os;
}
Node::Node(string _name): name(_name),next(NULL){};
#ifndef LINKLIST_H_
#define LINKLIST_H_
#include "Node.h"
using namespace std;
class LinkList
{
public:
//构造函数,在初始化一个新的LinkList时,我们定义了一个指向Node节点的指针head,
//该head指针指向了NULL(或者是0),表达为head = NULL;或者head = 0;
//如果head == NULL, 我们说这个链表是空链表。isEmpty()返回true。
LinkList():head(NULL),size(0){};
void addToHead(const string&);
void addToTail(const string&);
void showList();
bool isEmpty();
void insert(const string&);
int theSize();
void deleteNode(const string&);
void recursivePrintList();//递归打印,无需传入要节点,公有
~LinkList();
private:
Node *head;//head是一个指向一个Node类的指针
int size;
Node* findTail();//找到尾巴节点,私有函数
void recursivePrintList(Node*);//递归打印,需要传入节点,私有,不对用户暴露
};
#endif
LinkList类cpp
#include "LinkList.h"
using namespace std;
/* ---------------把新的节点加到链表的头部------------------------*/
void LinkList::addToHead(const string& name)
{
//每执行一次addToHead,我们就要新创建一个指向新Node的指针
//该Node接收了传入的name作为其数据域的值
//该Node的指针域自动初始化指向NULL。(Node的构造函数就是这样定义的)
//注意:newNode是指向新Node的指针。
Node* newNode = new Node(name);
//如果head指针指向了NULL,说明该链表还是空链表
//我们让head指针指向新建的这个Node;
if (isEmpty())
{
head = newNode;
}
//如果链表不是空的,head指针已经指向了某个Node。
//我们让新建的这个Node的next指针指向head指针所指向的那个节点;
//然后让head指针指向这个新建的Node
else
{
newNode->next = head;
head = newNode;
}
size++;
}
/* ---------------找到指向最后一个Node的那个指针-----------------*/
Node* LinkList::findTail()
{
//首先,新建一个Node指针,让这个指针指向第一个Node
Node *pTail = head;
//如果这个指针指向的节点还有后续节点的话,循环就继续
//直到找到指向最后节点的那个指针
while (pTail->next)
{
pTail = pTail->next;
}
return pTail;
}
bool LinkList::isEmpty()
{
return (head == NULL);
}
/* ---------------把新的节点加到链表的尾部------------------------*/
void LinkList::addToTail(const string& name)
{
Node *newNode = new Node(name);
if (isEmpty())
{
head = newNode;
}
else
{
Node *pTail = findTail();
pTail->next = newNode;
}
size++;
}
/* ---------------构造一个优先队列的链表------------------------*/
void LinkList::insert(const string& name)
{
Node* newNode = new Node(name);
//如果链表是空
//就让newNode指针成为指向第一个Node的指针
if(isEmpty())
{
head = newNode;
}
//如果链表非空
//定义两个指针,一个current指针,指向现在的节点
//一个previous指针,指向之前一个的节点
else
{
Node* curr = head;
Node* previous = NULL;
//遍历,找到要插入的位置
while (curr != NULL)
{
if (curr->name >= name)
{
break;
}
else
{
previous = curr;
curr = curr->next;
}
}
//如果要插入的位置是head;
if (curr == head)
{
newNode->next = head;
head = newNode;
}
//如果要插入的位置是中间某处或者链表尾巴(不是head)
else
{
newNode->next = curr;
previous->next = newNode;
}
}
size++;
}
int LinkList::theSize()
{
return size;
}
void LinkList::deleteNode(const string& name)
{
if (isEmpty())
{
cout << "Cannot delete a empty LinkList"<<endl;
}
else
{
Node* curr = head;
Node* previous = NULL;
while (curr != NULL)
{
if (curr->name == name)
{
break;
}
else
{
previous = curr;
curr = curr->next;
}
}
if (curr == NULL)
{
cout << "the name you want to delete was not found!"<<endl;
}
else if (curr == head)
{
head = curr->next;
}
else
{
previous->next = curr->next;
}
delete curr;
size--;
}
}
void LinkList::showList()
{
Node* pNode = head;
while(pNode != NULL)
{
cout << *pNode << endl;
pNode = pNode->next;
}
}
void LinkList::recursivePrintList()
{
recursivePrintList(head);
}
void LinkList::recursivePrintList(Node* pNode)
{
if (pNode != NULL)
{
/*------------如果交换下面两行的执行顺序的话,会怎么样?--------------*/
recursivePrintList(pNode->next); // (1)
cout << *pNode <<endl; //(2)
/*------------链表的打印次序会颠倒,为什么--------------*/
}
}
/*---------因为在main函数里有new建立的对象指针,需要重新写析构函数-----------*/
LinkList::~LinkList()
{
Node *p, *q;
for (p = head; p; p = q)
{
q = p->next;
//跟踪现在删掉了什么
cout << "now is deleting the node:";
cout << *p << " , 地址是: "<< p << endl;
delete p;
}
}
#include "LinkList.h"
using namespace std;
int main()
{
LinkList* lk = new LinkList();
string name = "None";
///*------------以下代码用来从头部插入节点-------------*/
// while (1)
// {
// cout << "Please input name, or q to quit: "<<endl;
//
// cin >> name;
// if (name == "q")
// break;
// else
// lk->addToHead(name);
// }
// lk->showList();
//
// cout << "-------------------" << endl;
//
///*------------以下代码用来从尾部插入节点-------------*/
// while (1)
// {
// cout << "Please input name, or q to quit: "<<endl;
//
// cin >> name;
// if (name == "q")
// break;
// else
// lk->addToTail(name);
// }
// lk->showList();
//
// cout << "-------------------" << endl;
/*------------以下代码用来插入节点,构造优先队列-------------*/
while (1)
{
cout << "Please input name, or q to quit: "<<endl;
cin >> name;
if (name == "q")
break;
else
lk->insert(name);
}
lk->showList();
cout << "-------------------" << endl;
/*------------以下代码用来delete某个节点-------------*/
while (1)
{
cout << "Please delete name, or q to quit: "<<endl;
cin >> name;
if (name == "q")
break;
else
lk->deleteNode(name);
}
lk->showList();
cout << "-------------------" << endl;
/*------------recursively打印出链表的元素-------------*/
lk->recursivePrintList();
cout << "-------------------" << endl;
cout << "the size of this linklist is: " << lk->theSize() << endl;
/*-------------需要手动释放 lk指针,否则析构函数不会自动执行
(因为lk是一个指向对象的指针,而不是对象)-------------------*/
delete lk;
return 0;
}