国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++實(shí)現(xiàn)單鏈表【每一步詳細(xì)深入講解,代碼清晰、簡(jiǎn)單、易懂】

這篇具有很好參考價(jià)值的文章主要介紹了C++實(shí)現(xiàn)單鏈表【每一步詳細(xì)深入講解,代碼清晰、簡(jiǎn)單、易懂】。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、單鏈表的結(jié)構(gòu)(以數(shù)據(jù)為不重復(fù)整數(shù)為例)

0、overview

鏈表元素由數(shù)據(jù)和指針構(gòu)成,因此鏈表的節(jié)點(diǎn)可以由一個(gè)包含這兩種元素的結(jié)構(gòu)體代表:

// 單鏈表節(jié)點(diǎn)
struct SingleListNode {
    int data;
    SingleListNode* next;
    SingleListNode(int val, SingleListNode* ptr = nullptr);
};

鏈表包含插入、刪除操作,而插入、刪除又必須先查找元素是否存在,因此查找方法也必不可少。

//單鏈表
class SingleList {
public:
    SingleListNode* dummy;
    SingleList();
    ~SingleList();
public:
    void add(int);
    void remove(int);
    SingleListNode* find(int);
};

1、插入操作

c++單鏈表,數(shù)據(jù)結(jié)構(gòu)與算法,c++,鏈表,數(shù)據(jù)結(jié)構(gòu)

例如:我們需要在偽頭節(jié)點(diǎn)(不包含數(shù)據(jù))和含有1的節(jié)點(diǎn)之間插入一個(gè)節(jié)點(diǎn),發(fā)現(xiàn),只需要改變dummy的指針和需要插入的指針即可。那么很容易想到下面的步驟:

  • 將dummy的指針指向要添加的節(jié)點(diǎn)

  • 將要添加節(jié)點(diǎn)的指針指向之前的下一個(gè)節(jié)點(diǎn)

c++單鏈表,數(shù)據(jù)結(jié)構(gòu)與算法,c++,鏈表,數(shù)據(jù)結(jié)構(gòu) c++單鏈表,數(shù)據(jù)結(jié)構(gòu)與算法,c++,鏈表,數(shù)據(jù)結(jié)構(gòu)

這樣我們就添加了一個(gè)節(jié)點(diǎn)。

但是發(fā)現(xiàn)了一個(gè)問(wèn)題:因?yàn)閱蜗蜴湵碇荒?strong>通過(guò)前一個(gè)的指針尋找下一個(gè)元素,如果該指針指向改變了,我們就永遠(yuǎn)也找不到下一個(gè)元素了,因此,上面步驟2是錯(cuò)誤的。那我們應(yīng)該如何添加元素?

正確的添加順序

  • 先將要添加的元素的指針指向dummy節(jié)點(diǎn)的后一個(gè)節(jié)點(diǎn)

  • 再將dummy節(jié)點(diǎn)的指針指向要添加的節(jié)點(diǎn)

c++單鏈表,數(shù)據(jù)結(jié)構(gòu)與算法,c++,鏈表,數(shù)據(jù)結(jié)構(gòu) c++單鏈表,數(shù)據(jù)結(jié)構(gòu)與算法,c++,鏈表,數(shù)據(jù)結(jié)構(gòu)

插入的情況討論

  • 插入時(shí)這里為了方便統(tǒng)一在dummy節(jié)點(diǎn)之后插入,也即每次插入一個(gè)新元素都在開(kāi)頭插入

圖例:

初始 插入2 插入3
c++單鏈表,數(shù)據(jù)結(jié)構(gòu)與算法,c++,鏈表,數(shù)據(jù)結(jié)構(gòu) c++單鏈表,數(shù)據(jù)結(jié)構(gòu)與算法,c++,鏈表,數(shù)據(jù)結(jié)構(gòu) c++單鏈表,數(shù)據(jù)結(jié)構(gòu)與算法,c++,鏈表,數(shù)據(jù)結(jié)構(gòu)

插入的代碼邏輯

  • 讀取find函數(shù)返回值判讀元素是否已存在
  • 存在則輸出插入失敗,并返回
  • 不存在則執(zhí)行插入操作
void SingleList::add(int val) {
    auto ptr = find(val);
    if (ptr) {
        std::cerr << val << " exists, add failed!" << std::endl;
        return;
    } else {
        auto temp = new SingleListNode(val);
        temp->next = dummy->next;
        dummy->next = temp;
    }
}

2、刪除操作

相比于插入,刪除要簡(jiǎn)單一些

c++單鏈表,數(shù)據(jù)結(jié)構(gòu)與算法,c++,鏈表,數(shù)據(jù)結(jié)構(gòu)

例如我們要?jiǎng)h除上圖包含2的節(jié)點(diǎn),只需執(zhí)行下面的步驟

  • 將需要?jiǎng)h除的節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)的指針指向需要?jiǎng)h除的節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn),也即dummy的節(jié)點(diǎn)指向1
  • 再將需要?jiǎng)h除的節(jié)點(diǎn)釋放掉
c++單鏈表,數(shù)據(jù)結(jié)構(gòu)與算法,c++,鏈表,數(shù)據(jù)結(jié)構(gòu) c++單鏈表,數(shù)據(jù)結(jié)構(gòu)與算法,c++,鏈表,數(shù)據(jù)結(jié)構(gòu)

刪除的代碼邏輯

  • 讀取find函數(shù)的返回值判斷元素是否存在
  • 不存在則輸出錯(cuò)誤提示并返回
  • 存在則執(zhí)行刪除操操作
void SingleList::remove(int val) {
    auto ptr = find(val);
    if (ptr == nullptr) {
        std::cerr << val << " does not exist, remove failed!" << std::endl;
        return;
    } else {
        auto temp = ptr->next;
        ptr->next = ptr->next->next;
        delete temp;
    }
}

3、查找操作

通過(guò)對(duì)插入和刪除的討論,我們了解到,插入調(diào)用find函數(shù)時(shí),并不需要操作其返回值,所以,返回值具體是該元素的節(jié)點(diǎn)還是其前面的節(jié)點(diǎn)并沒(méi)有影響;但是,由于單鏈表只能通過(guò)前一個(gè)的指針尋找下一個(gè)元素,因此,刪除操作時(shí)我們必須得到需要?jiǎng)h除節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn),因此find的返回值必須設(shè)為需要尋找的節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn),而第一個(gè)節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)是dummy,這也是我們需要dummy這個(gè)偽頭節(jié)點(diǎn)的原因之一。

查找代碼的邏輯

  • 從第一個(gè)含有元素的節(jié)點(diǎn)開(kāi)始尋找,依次向后
  • 如果找到該節(jié)點(diǎn),則返回之
  • 如果鏈表遍歷完也沒(méi)有找到,就返回nullptr
SingleListNode* SingleList::find(int val) {
    auto prev = dummy;
    auto temp = dummy->next;
    while (temp) {
        if (temp->data == val)
            return prev;
        prev = prev->next;
        temp = temp->next;
    }
    return nullptr;
}

循環(huán)鏈表的查找

當(dāng)單鏈表為循環(huán)鏈表時(shí),最后一個(gè)元素的next指針不是指向nullptr,而是dummy節(jié)點(diǎn),因此,查找代碼有一些小變化,同時(shí)構(gòu)造、析構(gòu)以及測(cè)試代碼都圍繞dummy的next指針有相應(yīng)的小變化(詳見(jiàn)代碼)

SingleListNode* SingleList::find(int val) {
    auto prev = dummy;
    auto temp = dummy->next;
    while (temp != dummy) {	//循環(huán)條件變?yōu)閠emp不等于dummy
        if (temp->data == val)
            return prev;
        prev = prev->next;
        temp = temp->next;
    }
    return nullptr;
}

4、完整代碼

// SingleList.h 單鏈表類定義

// 單鏈表節(jié)點(diǎn)
struct SingleListNode {
    int data;
    SingleListNode* next;
    SingleListNode(int val, SingleListNode* ptr = nullptr);
};

//單鏈表
class SingleList {
public:
    SingleListNode* dummy;
    SingleList();
    ~SingleList();
public:
    void add(int);
    void remove(int);
    SingleListNode* find(int);
};
// SingleList.cpp 單鏈表類的函數(shù)實(shí)現(xiàn)及靜態(tài)成員定義
#include <iostream>
#include "SingleList.h"

SingleListNode::SingleListNode(int val, SingleListNode* ptr)
    : data(val), next(ptr) { }

SingleList::SingleList() : dummy(new SingleListNode(-1)) { }

SingleList::~SingleList() {
    auto ptr = dummy->next;
    while (ptr) {
        auto temp = ptr;
        ptr = ptr->next;
        delete temp;
        std::cout << "Element deleted!" << std::endl;
    }
    delete dummy;
    std::cout << "SingleList Destroyed!" << std::endl;
}

void SingleList::add(int val) {
    auto ptr = find(val);
    if (ptr) {
        std::cerr << val << " exists, add failed!" << std::endl;
        return;
    } else {
        auto temp = new SingleListNode(val);
        temp->next = dummy->next;
        dummy->next = temp;
    }
}

void SingleList::remove(int val) {
    auto ptr = find(val);
    if (ptr == nullptr) {
        std::cerr << val << " does not exist, remove failed!" << std::endl;
        return;
    } else {
        auto temp = ptr->next;
        ptr->next = ptr->next->next;
        delete temp;
    }
}

SingleListNode* SingleList::find(int val) {
    auto prev = dummy;
    auto temp = dummy->next;
    while (temp) {
        if (temp->data == val)
            return prev;
        prev = prev->next;
        temp = temp->next;
    }
    return nullptr;
}
// SingleListTest.cpp 對(duì)該單鏈表的測(cè)試代碼

#include <iostream>
#include "SingleList.h"

int main(void) {
	SingleList list;

	list.add(0);
	list.add(1);
	list.add(2);
	list.add(3);
	list.add(4);
	list.add(4);	// 添加已存在元素
	list.remove(0); // 末尾元素
	list.remove(2); // 中間元素
	list.remove(4); // 開(kāi)頭元素
	list.remove(4); // 刪除不存在元素
	for (auto temp = list.dummy->next; temp; temp = temp->next)
		std::cout << temp->data << " ";
	std::cout << std::endl;
	/*期望的輸出
	4 exists, add failed!
	4 does not exist, remove failed!
	3 1
	Element deleted!
	Element deleted!
	SingleList Destroyed!
	*/
	return 0;
}

5、循環(huán)鏈表的代碼

鏈表的結(jié)構(gòu)僅有查找函數(shù)有變化同時(shí),測(cè)試的代碼也有相應(yīng)的變化文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-716894.html

// SingleList.h 單循環(huán)鏈表類定義

// 單循環(huán)鏈表節(jié)點(diǎn)
struct SingleListNode {
    int data;
    SingleListNode* next;
    SingleListNode(int val, SingleListNode* ptr = nullptr);
};

//單循環(huán)鏈表
class SingleList {
public:
    SingleListNode* dummy;
    SingleList();
    ~SingleList();
public:
    void add(int);
    void remove(int);
    SingleListNode* find(int);
};
// SingleList.cpp 單循環(huán)鏈表類的函數(shù)實(shí)現(xiàn)及靜態(tài)成員定義
#include <iostream>
#include "SingleList.h"

SingleListNode::SingleListNode(int val, SingleListNode* ptr)
    : data(val), next(ptr) { }

SingleList::SingleList() 
    : dummy(new SingleListNode(-1)) { // 構(gòu)造dummy時(shí),需要把next指向本身
    dummy->next = dummy; 
}

SingleList::~SingleList() {
    auto ptr = dummy->next;
    while (ptr != dummy) { // 析構(gòu)條件變?yōu)閜tr != dummy
        auto temp = ptr;
        ptr = ptr->next;
        delete temp;
        std::cout << "Element deleted!" << std::endl;
    }
    delete dummy;
    std::cout << "SingleList Destroyed!" << std::endl;
}

void SingleList::add(int val) {
    auto ptr = find(val);
    if (ptr) {
        std::cerr << val << " exists, add failed!" << std::endl;
        return;
    } else {
        auto temp = new SingleListNode(val);
        temp->next = dummy->next;
        dummy->next = temp;
    }
}

void SingleList::remove(int val) {
    auto ptr = find(val);
    if (ptr == nullptr) {
        std::cerr << val << " does not exist, remove failed!" << std::endl;
        return;
    } else {
        auto temp = ptr->next;
        ptr->next = ptr->next->next;
        delete temp;
    }
}

SingleListNode* SingleList::find(int val) {
    auto prev = dummy;
    auto temp = dummy->next;
    while (temp != dummy) { //循環(huán)條件變?yōu)閠emp不等于dummy
        if (temp->data == val)
            return prev;
        prev = prev->next;
        temp = temp->next;
    }
    return nullptr;
}
// SingleListTest.cpp 對(duì)該單循環(huán)鏈表的測(cè)試代碼

#include <iostream>
#include "SingleList.h"

int main(void) {
	SingleList list;

	list.add(0);
	list.add(1);
	list.add(2);
	list.add(3);
	list.add(4);
	list.add(4);	// 添加已存在元素
	list.remove(0); // 末尾元素
	list.remove(2); // 中間元素
	list.remove(4); // 開(kāi)頭元素
	list.remove(4); // 刪除不存在元素
	for (auto temp = list.dummy->next; temp != list.dummy; temp = temp->next) // 循環(huán)鏈表循環(huán)條件為temp != list.dummy
		std::cout << temp->data << " ";
	std::cout << std::endl;
	/*期望的輸出
	4 exists, add failed!
	4 does not exist, remove failed!
	3 1
	Element deleted!
	Element deleted!
	SingleList Destroyed!
	*/
	return 0;
}

到了這里,關(guān)于C++實(shí)現(xiàn)單鏈表【每一步詳細(xì)深入講解,代碼清晰、簡(jiǎn)單、易懂】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【計(jì)算機(jī)基礎(chǔ)】Git從安裝到使用,詳細(xì)每一步!擴(kuò)展Github\Gitlab

    【計(jì)算機(jī)基礎(chǔ)】Git從安裝到使用,詳細(xì)每一步!擴(kuò)展Github\Gitlab

    ??:如果你也對(duì)機(jī)器人、人工智能感興趣,看來(lái)我們志同道合? ??:不妨瀏覽一下我的博客主頁(yè)【https://blog.csdn.net/weixin_51244852】 ??:文章若有幸對(duì)你有幫助,可點(diǎn)贊 ?? 收藏 ?不迷路?? ??:內(nèi)容若有錯(cuò)誤,敬請(qǐng)留言 ??指正!原創(chuàng)文,轉(zhuǎn)載請(qǐng)注明出處 ?? 誕生 :2005年

    2024年02月09日
    瀏覽(32)
  • Centos7下的DNS服務(wù)器部署(每一步圖文結(jié)合超詳細(xì),適用于初學(xué)者)

    Centos7下的DNS服務(wù)器部署(每一步圖文結(jié)合超詳細(xì),適用于初學(xué)者)

    關(guān)于DNS服務(wù),網(wǎng)上都有很多很詳細(xì)很專業(yè)的講解,但是對(duì)于大部分初學(xué)者可能看的比較懵懂,用白話來(lái)說(shuō)就是起初人們因?yàn)閷?duì)大量用于訪問(wèn)服務(wù)器的IP地址難以記住,所以就逐漸出現(xiàn)了域名的形式(諸如:www.baidu.com 之類的),但是計(jì)算機(jī)本身只能識(shí)別出像192.168.10.112之類的

    2024年02月07日
    瀏覽(30)
  • 【數(shù)據(jù)結(jié)構(gòu)】單鏈表 | 詳細(xì)講解

    【數(shù)據(jù)結(jié)構(gòu)】單鏈表 | 詳細(xì)講解

    無(wú)須為了表示中間的元素之間的邏輯關(guān)系而增加額外的存儲(chǔ)空間; 因?yàn)橐詳?shù)組形式存儲(chǔ),可以快速地存取表中任一位置的元素。 插入和刪除操作需要移動(dòng)大量元素,時(shí)間復(fù)雜度為O(N); 當(dāng)線性表長(zhǎng)度變化較大時(shí),難以確定存儲(chǔ)空間的容量; 造成存儲(chǔ)空間的“碎片”。 其實(shí)順

    2024年02月05日
    瀏覽(23)
  • 高精度除法【c++實(shí)現(xiàn)】超詳細(xì)講解

    高精度算法分為兩種,高精除以低精和高精除以高精。不要看都是除法,就認(rèn)為原理類似,其實(shí)是有很大差距的。讓我們一起來(lái)學(xué)習(xí)吧! 有句話說(shuō)在前面,如果除數(shù)等于0,就不要算了,不成立。( 如果你忘了這個(gè)知識(shí),小學(xué)數(shù)學(xué)老師饒不了你 ) 高精度除低精度,原理是模

    2024年02月13日
    瀏覽(92)
  • UniApp 中的路由守衛(wèi)與攔截器:守護(hù)應(yīng)用的每一步

    正文: 路由守衛(wèi)和攔截器在前端開(kāi)發(fā)中扮演著重要的角色,它們可以用來(lái)控制頁(yè)面訪問(wèn)權(quán)限、全局請(qǐng)求攔截等。在 UniApp 中,路由守衛(wèi)和攔截器同樣具有強(qiáng)大的功能,能夠保護(hù)應(yīng)用的安全和穩(wěn)定性。本文將深入探討 UniApp 中的路由守衛(wèi)和攔截器,帶你領(lǐng)略它們的魔法與神奇。

    2024年04月25日
    瀏覽(22)
  • 二分查找算法講解及其C++代碼實(shí)現(xiàn)

    二分查找算法是一種常用的查找算法,也被稱為折半查找。它可以在有序的數(shù)組或列表中快速查找需要的元素。 算法描述: 首先確定數(shù)組的中間位置mid=(left+right)/2; 然后將要查找的值key與中間位置的值進(jìn)行比較; 如果key等于中間位置的值,則查找成功,返回mid; 如果key小

    2024年02月01日
    瀏覽(41)
  • 網(wǎng)絡(luò)流的C++代碼實(shí)現(xiàn)與過(guò)程講解

    網(wǎng)絡(luò)流是一種非常重要的圖論算法,它在許多實(shí)際問(wèn)題中得到廣泛應(yīng)用。本文將介紹網(wǎng)絡(luò)流算法的C++代碼實(shí)現(xiàn)與過(guò)程講解。 網(wǎng)絡(luò)流算法是通過(guò)將圖中的邊看作流量通道,將圖的點(diǎn)看作流量的起點(diǎn)或終點(diǎn),來(lái)求解圖中的最大或最小流量的問(wèn)題。它是一種非常重要的最優(yōu)化算法,

    2023年04月21日
    瀏覽(15)
  • 如何仿寫簡(jiǎn)易tomcat 實(shí)現(xiàn)思路+代碼詳細(xì)講解

    如何仿寫簡(jiǎn)易tomcat 實(shí)現(xiàn)思路+代碼詳細(xì)講解

    仿寫之前,我們要搞清楚都要用到哪些技術(shù) 自定義注解,比如Tomcat使用的是@Servlet,我們可以定義一個(gè)自己的@MyServlet 構(gòu)造請(qǐng)求體和返回體,比如tomcat使用HttpRequest,我們可以自己定義myHttpRequest java去遍歷一個(gè)指定目錄,然后獲取到.java文件,再獲取到帶有@MyServlet注解的類 然

    2024年02月12日
    瀏覽(20)
  • [C++]:萬(wàn)字超詳細(xì)講解多態(tài)以及多態(tài)的實(shí)現(xiàn)原理(面試的必考的c++考點(diǎn))

    [C++]:萬(wàn)字超詳細(xì)講解多態(tài)以及多態(tài)的實(shí)現(xiàn)原理(面試的必考的c++考點(diǎn))

    文章目錄 前言 一、多態(tài)的定義及實(shí)現(xiàn) 1.多態(tài)的構(gòu)成條件 2.c++11的override和final 3.重載,重寫,重定義的比較 4.抽象類 5.多態(tài)的原理 6.多繼承中的虛函數(shù)表 7.動(dòng)態(tài)綁定和靜態(tài)綁定 總結(jié) 多態(tài)的概念: 多態(tài)的概念:通俗來(lái)說(shuō),就是多種形態(tài), 具體點(diǎn)就是去完成某個(gè)行為,當(dāng)不同的

    2023年04月22日
    瀏覽(23)
  • 基于SpringBoot實(shí)現(xiàn)文件上傳和下載(詳細(xì)講解And附完整代碼)

    目錄 一、基于SpringBoot實(shí)現(xiàn)文件上傳和下載基于理論 二、詳細(xì)操作步驟 文件上傳步驟: 文件下載步驟: 三、前后端交互原理解釋? 四、小結(jié)? 博主介紹:?專注于前后端領(lǐng)域開(kāi)發(fā)的優(yōu)質(zhì)創(chuàng)作者、秉著互聯(lián)網(wǎng)精神開(kāi)源貢獻(xiàn)精神,答疑解惑、堅(jiān)持優(yōu)質(zhì)作品共享。本人是掘金/騰訊

    2024年04月11日
    瀏覽(118)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包