博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++单链表【构造函数、运算符重载、析构函数、增删查改等】
阅读量:4030 次
发布时间:2019-05-24

本文共 5006 字,大约阅读时间需要 16 分钟。

c++中的单向链表写法:实现增删查改、构造函数、运算符重载、析构函数等。

建立头文件SList.h

#pragma oncetypedef int DataType;//SList要访问SListNode,可以通过友元函数实现,友元函数在被访问的类中class SListNode{	friend class SList;//友元函数public:	SListNode(const DataType x)		:_data(x)		, _next(NULL)	{}private:	SListNode* _next;	DataType _data;};class SList{public:	SList()		:_head(NULL)		, _tail(NULL)	{}	//深拷贝	SList(const SList& s)		:_head(NULL)		, _tail(NULL)	{		SListNode* cur = s._head;		while (cur)		{			this->PushBack(cur->_data);			cur = cur->_next;		}	}	深拷贝的传统写法	//SList& operator=(const SList& s)	//{	//	if (this != &s)	//	{	//		Clear();	//		SListNode* cur = s._head;	//		while (cur)	//		{	//			this->PushBack(cur->_data);	//			cur = cur->_next;	//		}	//	}	//	return *this;	//}	//深拷贝的现代写法	SList& operator=(SList& s)	{		swap(_head, s._head);		swap(_tail, s._tail);		return *this;	}	~SList()	{		Clear();	}public:	void Clear();	void PushBack(DataType x);	void PopBack();	void PushFront(DataType x);	void PopFront();	//void Insert(size_t pos,DataType x);	void Insert(SListNode* pos, DataType x);	void Erase(SListNode* pos);	SListNode* Find(DataType x);	void PrintSList();private:	SListNode* _head;	SListNode* _tail;};

各函数的实现

#include
using namespace std;#include"SList.h"#include
void SList::Clear(){ SListNode* cur = _head; while (cur) { SListNode* del = cur; cur = cur->_next; delete del;      del = NULL; }}void SList::PrintSList()//打印链表{ SListNode* cur = _head; while (cur) { cout << cur->_data << "->"; cur = cur->_next; } cout << "NULL" << endl;}void SList::PushBack(DataType x)//尾插{ if (NULL == _head) { _head = new SListNode(x);//开辟一个值为x的新结点 _tail = _head; } else { //SListNode* cur; //cur->_data = x;     //_tail->_next = cur; //_tail = cur; _tail->_next= new SListNode(x); _tail = _tail->_next; }}void SList::PopBack()//尾删{ if (NULL == _head) { cout << "SList is empty!" << endl; } else if (_head == _tail) { delete _head; _head = _tail = NULL; } else { SListNode* cur = _head;//找到要删除尾节点的前一个节点cur while (cur->_next->_next) { cur = cur->_next; } delete cur->_next; cur->_next = NULL; _tail = cur; }}void SList::PushFront(DataType x)//头插{ SListNode* tmp = _head; _head=new SListNode(x); _head->_next = tmp;}void SList::PopFront()//头删{ if (NULL == _head) { cout << "SList is empty!" << endl; } else if (NULL == _head->_next) { delete _head; _head = NULL;//delete后要将指针设空,否则产生野指针 } else { SListNode* tmp = _head->_next; delete _head;  _head = tmp; }}//void SList::Insert(size_t pos, DataType x)//{// assert(pos);// SListNode* tmp = _head;// pos -= 1;// while (--pos)// {// tmp = tmp->_next;// }// if (NULL == tmp)// SList::PushBack(x);// else// {// SListNode* next = tmp->_next;// SListNode* cur = new SListNode(x);// tmp->_next = cur;// cur->_next = next;// }//}void SList::Insert(SListNode* pos, DataType x)指定位置处插入x{ assert(pos); SListNode* tmp = _head; while (tmp) { if (NULL == tmp->_next) SList::PushFront(x); else if (pos == tmp->_next) { SListNode* cur = new SListNode(x); cur->_next= tmp->_next; tmp->_next = cur; return;//注意结束循环 } tmp = tmp->_next; }}void SList::Erase(SListNode* pos){ assert(pos); SListNode* tmp = _head; while (tmp) { if (NULL == tmp->_next) SList::PopFront(); else if (pos == tmp->_next) { SListNode* cur = tmp->_next->_next; delete tmp->_next; tmp->_next = NULL; tmp->_next = cur; return;//注意结束循环 } tmp = tmp->_next; }}SListNode* SList::Find(DataType x){ SListNode* cur = _head; while (cur) { if (x == cur->_data) { return cur; } cur = cur->_next; } return NULL;}

各操作的测试用例

void Test1(){//尾插尾删	SList S;	S.PushBack(1);	S.PushBack(2);	S.PushBack(3);	S.PushBack(4);	S.PrintSList();	S.PopBack();	S.PrintSList();	//S.PopBack();	//S.PopBack();	//S.PrintSList();	//S.PopBack();	//S.PopBack();	//S.PopBack();	SList S1(S);	S1.PrintSList();	SList S2;	S2 = S;	S2.PrintSList();}void Test2(){//头插头删	SList S;	S.PushFront(1);	S.PushFront(2);	S.PushFront(3);	S.PushFront(4);	S.PrintSList();	S.PopFront();	S.PrintSList();	S.PopFront();	S.PopFront();	S.PopFront();	S.PrintSList();	S.PopFront();}void Test3(){//指定位置插入某数,查找某数	SList S;	S.PushBack(1);	S.PushBack(2);	S.PushBack(4);	S.PushBack(5);	S.PrintSList();	//S.Insert(3, 3);	SListNode* p = S.Find(4);	S.Insert(p, 3);	S.PrintSList();}void Test4(){//删除某结点	SList S;	S.PushBack(1);	S.PushBack(2);	S.PushBack(3);	S.PushBack(10);	S.PushBack(4);	S.PushBack(5);	S.PrintSList();	SListNode* p = S.Find(10);	S.Erase(p);	S.PrintSList();}

友元函数

     在实现类之间数据共享时,减少系统开销,提高效率。如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数。具体来说:为了使其他类的成员函数直接访问该类的私有变量。即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数。

实际上具体大概有下面两种情况需要使用友元函数:

(1)运算符重载的某些场合需要使用友元。

(2)两个类要共享数据的时候。

1.1使用友元函数的优缺点

优点:能够提高效率,表达简单、清晰。

缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数。

1.2友元函数的参数

因为友元函数没有this指针,则参数要有三种情况:

(1) 要访问非static成员时,需要对象做参数;

(2)要访问static成员或全局变量时,则不需要对象做参数;

(3)如果做参数的对象是全局对象,则不需要对象做参数;

1.3友元函数的位置

因为友元函数是类外的函数,所以它的声明可以放在类的私有段或公有段且没有区别。

1.4友元函数的调用

可以直接调用友元函数,不需要通过对象或指针

友元函数和类的成员函数的区别

成员函数有this指针,而友元函数没有this指针。

友元函数是不能被继承的,就像父亲的朋友未必是儿子的朋友。

本文出自 “” 博客,请务必保留此出处

转载地址:http://lnlbi.baihongyu.com/

你可能感兴趣的文章
VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
查看>>
VUE-Vue.js之$refs,父组件访问、修改子组件中 的数据
查看>>
Vue-子组件改变父级组件的信息
查看>>
Python自动化之pytest常用插件
查看>>
Python自动化之pytest框架使用详解
查看>>
【正则表达式】以个人的理解帮助大家认识正则表达式
查看>>
性能调优之iostat命令详解
查看>>
性能调优之iftop命令详解
查看>>
非关系型数据库(nosql)介绍
查看>>
移动端自动化测试-Windows-Android-Appium环境搭建
查看>>
Xpath使用方法
查看>>
移动端自动化测试-Mac-IOS-Appium环境搭建
查看>>
Selenium之前世今生
查看>>
Selenium-WebDriverApi接口详解
查看>>
Selenium-ActionChains Api接口详解
查看>>
Selenium-Switch与SelectApi接口详解
查看>>
Selenium-Css Selector使用方法
查看>>
Linux常用统计命令之wc
查看>>
测试必会之 Linux 三剑客之 sed
查看>>
Socket请求XML客户端程序
查看>>