日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++单链表【构造函数、运算符重载、析构函数、增删查改等】

發布時間:2023/12/10 c/c++ 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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++单链表【构造函数、运算符重载、析构函数、增删查改等】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。