c++单链表【构造函数、运算符重载、析构函数、增删查改等】
2016-06-11 18:52
363 查看
c++中的单向链表写法:实现增删查改、构造函数、运算符重载、析构函数等。建立头文件SList.h
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();
}[/code]友元函数 在实现类之间数据共享时,减少系统开销,提高效率。如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数。具体来说:为了使其他类的成员函数直接访问该类的私有变量。即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数。实际上具体大概有下面两种情况需要使用友元函数:(1)运算符重载的某些场合需要使用友元。(2)两个类要共享数据的时候。1.1使用友元函数的优缺点优点:能够提高效率,表达简单、清晰。缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数。1.2友元函数的参数因为友元函数没有this指针,则参数要有三种情况:(1) 要访问非static成员时,需要对象做参数;(2)要访问static成员或全局变量时,则不需要对象做参数;(3)如果做参数的对象是全局对象,则不需要对象做参数;1.3友元函数的位置因为友元函数是类外的函数,所以它的声明可以放在类的私有段或公有段且没有区别。1.4友元函数的调用可以直接调用友元函数,不需要通过对象或指针友元函数和类的成员函数的区别成员函数有this指针,而友元函数没有this指针。友元函数是不能被继承的,就像父亲的朋友未必是儿子的朋友。本文出自 “Scen” 博客,请务必保留此出处http://10741357.blog.51cto.com/10731357/1748574
#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;//找到要删除尾节点的前一个节点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();
}[/code]友元函数 在实现类之间数据共享时,减少系统开销,提高效率。如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数。具体来说:为了使其他类的成员函数直接访问该类的私有变量。即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数。实际上具体大概有下面两种情况需要使用友元函数:(1)运算符重载的某些场合需要使用友元。(2)两个类要共享数据的时候。1.1使用友元函数的优缺点优点:能够提高效率,表达简单、清晰。缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数。1.2友元函数的参数因为友元函数没有this指针,则参数要有三种情况:(1) 要访问非static成员时,需要对象做参数;(2)要访问static成员或全局变量时,则不需要对象做参数;(3)如果做参数的对象是全局对象,则不需要对象做参数;1.3友元函数的位置因为友元函数是类外的函数,所以它的声明可以放在类的私有段或公有段且没有区别。1.4友元函数的调用可以直接调用友元函数,不需要通过对象或指针友元函数和类的成员函数的区别成员函数有this指针,而友元函数没有this指针。友元函数是不能被继承的,就像父亲的朋友未必是儿子的朋友。本文出自 “Scen” 博客,请务必保留此出处http://10741357.blog.51cto.com/10731357/1748574
相关文章推荐
- c++双链表【构造函数、运算符重载、析构函数、增删查改及逆置等】
- c++顺序表【构造函数、运算符重载、析构函数、增删查改等】
- C++用模板实现顺序表和栈
- C++用模板实现双链表和队列
- 【C++】智能指针shared_ptr 定位删除器(仿函数)
- 浅析c++异常
- C++之虚继承
- C语言 在屏幕上输出菱形图案
- C语言 求出100~999之间的所有“水仙花数”并输出
- C语言:编写strcpy函数
- C语言打印100 ——200之间的素数
- C语言判断1000—2000年之间的闰年
- C语言中不允许创建临时变量,交换两个数的内容
- C语言中写一个函数返回参数二进制中 1 的个数
- C语言求两个数中最大公约数
- 第14周项目3--数组类模板
- T2:滑雪(cowski.pas/c/cpp)
- notepad++搭建C语言环境(Dev c++)
- C语言动态和静态内存分配
- C语言结构体