单链表的c++实现

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){};


LinkList类头文件
#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;
	}
}


 测试LinkListApp.cpp
#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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值