c++单链表【构造函数、运算符重载、析构函数、增删查改等】
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<iostream>
using namespace std;#include"SList.h"
#include<assert.h>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;//找到要删除尾节点的前一个节点curwhile (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指针。
友元函数是不能被继承的,就像父亲的朋友未必是儿子的朋友。
转载于:https://blog.51cto.com/luoyafei/1748574
c++单链表【构造函数、运算符重载、析构函数、增删查改等】相关推荐
- 单链表的增删查改等基本操作C++实现
单链表的初始化.增删查改.遍历一次找中间结点.删除一个无头单链表的非尾结点(不给头结点) #include<stdio.h> #include<stdlib.h> #inclu ...
- (不带头结点的)单链表增删查改,逆置单链表(两种方法),求两个单链表的第一个公共结点,合并两个单链表,单循环链表中判断第一个入环点,约瑟夫环
补充了每个算法的基本思想,并且画了思路图,源代码都经过调试成功 1.SlistNode.c文件 (1) (不带头结点的)单链表增删查改 #include "SlistNode.h" ...
- 数据结构之单链表的增删查改等操作画图详解
单链表 文章目录 单链表 链表的概念及其结构 概念 结构 链表的实现 开辟一个新结点 链表的销毁 打印链表 单链表的尾插 单链表的头插 单链表的头删 单链表的尾删 找到单链表中的一个结点 在pos位置 ...
- 【顺序表和链表】实现增删查改数据结构 OJ题编程
目录 线性表 一.顺序表 1.使用顺序表MyArrayList增删查改 MyArrayList.java TestDemo.java 二.链表 1.带头 / 不带头 循环 / 非循环 2.创建链表并访 ...
- 【数据结构】链表:带头双向循环链表的增删查改
本篇要分享的内容是带头双向链表,以下为本片目录 目录 一.链表的所有结构 二.带头双向链表 2.1尾部插入 2.2哨兵位的初始化 2.3头部插入 2.4 打印链表 2.5尾部删除 2.6头部删除 2. ...
- python单链表操作_单链表的创建、增删改查等操作(Python实现)
单链表的创建.增删改查等操作(Python实现) # 单链表 class Node: def __init__(self, elem): self.elem = elem self.next = No ...
- Java——链表的增删查改
[基础学习] 链表的增删查改 注意:所有链表都先需要判断是否为null <1>链表的增 有三种方法,分别为:头插法,尾插法,任意节点位置插法 1.头插法 2.尾插法 3.任意节点位置插法 ...
- 单链表的实现与增删改查
单链表的实现与CRUD 单链表的实现与增删改查 链表实现 结果: Hero{id=1, name='dog1', otherName='aadog1'} Hero{id=2, name='dog2', ...
- 【C++ 语言】vector 容器 ( 容器分类 | vector 声明 | vector 初始化 | vector 容器元素增删查改 )
文章目录 序列式容器 vector 简介 vector ( 向量 ) 头文件 vector ( 向量 ) 声明及初始化 vector ( 向量 ) 添加元素 vector ( 向量 ) 查询元素 ve ...
最新文章
- AWS Storage Gateway 分类
- C# ICSharpCode.SharpZipLib.Zip 的使用
- Compose 手势事件:防止重复点击,双击,长按,全局触摸隐藏键盘
- python 读写函数
- Android布局属性详解之RelativeLayout
- linux 虚拟文件系统 源码,Linux内核源代码情状分析-虚拟文件系统
- ubuntu下c 调用java_ubuntu下使用JNI Java调用C++的例子
- Spring MVC 关于分页的简单实现
- 9. Linux 磁盘与文件管理系统(inode 目录)
- android谷歌打印插件下载地址,谷歌浏览器打印插件:Print Plus
- C++学习(四六六)Multiple parse contexts are available for this file
- 线性稳压芯片的优势及注意事项
- Falsy Bouncer(算法)
- 完美解决异常问题UnicodeEncodeError: ‘ascii‘ codec can‘t encode characters in position 0-7: ordinal not in ra
- 人形机器人视觉处理——走迷宫
- 游戏引擎除了开发游戏还能做什么?
- 突破!龙芯国产域名服务器+红枫2.0 底层技术问题再进一步
- Android Studio 使用Vuforia(高通)开发AR
- java毕业设计艾灸减肥管理网站Mybatis+系统+数据库+调试部署
- python是一种跨平台开源免费的高级动态编程语言_Python是一种跨平台、开源、免费的高级动态编程语言。...