【Linux 完整测试代码】数据结构之双向链表

阅读: 评论:0

【Linux 完整测试代码】数据结构之双向链表

【Linux 完整测试代码】数据结构之双向链表

别摸鱼啦,说的就是你,学习编程从入门到放弃。掌握编程思维方式,远胜于死记硬背编程语法,不能再迷路了。

双向链表                                           

图一 双向链表结构示意图

图二 双向链表创建流程示意图

为了清晰的理解双向链表的创建操作,请参考链表创建流程示意图。以下为双向链表创建步骤解析

/* 1. 当前节点的nextNode指向newNode 2. newNode的previoueNode指向currentNode3. newNode的nextNode指向nullptr防止出现野指针4. currentNode指向新创建的节点(newNode)
*/
currentNode->nextNode = staffInfo;
newNode->previousNode = currentNode;
newNode->nextNode = nullptr;
currentNode = newNode;

双向链表的操作比较常见,肯定难不倒机智的小伙伴,咱们就直接进阶到双向循环链表一探究竟啦


双向循环链表

图三 双向链表结构示意图


双向循环链表创建操作

双向循环链表的核心思想是 双向、循环,也就是说要能够双向操作并且形成闭环,图文详解双向循环链表创建过程:


1. 新建节点


2. 头节点的previousNode 指向newNode


3. currentNode和newNode互相指向


4. newNode的previousNode指向头节点


第五步 currentNode指向newNode, 至此 双向、循环 完成闭环

/* 1. 头节点previousNode指向newNode 2. 当前节点的nextNode指向newNode 3. newNode的previoueNode指向currentNode3. newNode的nextNode指向头节点4. currentNode指向新创建的节点(newNode)
*/headerNode->previousNode = newNode;
currentNode->nextNode = newNode;
newNode->previousNode = currentNode;
newNode->nextNode = headerNode;
currentNode = newNode;

双向循环链表创建核心代码  

为防止出现野指针需要将尾部node的nextNode指向nullptr

myData* headerNode, *currentNode;void DoubleLinkedList::createLinkedList()
{myData* newNode = new myData{0};if (!headerNode && !currentNode) {headerNode = currentNode = newNode;} else {headerNode->previousNode = newNode;currentNode->nextNode = newNode;newNode->previousNode = currentNode;newNode->nextNode = headerNode;currentNode = newNode;}
}

双向链表的插入操作也是个技术活,下面开始图文并茂, 注意有细节哦

1.  找到要插入的节点位置myNode

2. 注意点来了,划重点要考的 

  • 先是 newNode的nextNode 指向 myNode的nextNode

  • 然后 myNode的nextNode 记作myNode_1

  • 之后 myNode_1的previousNode 指向newNode

3.  最后一步 myNode的nextNode指向newNode


双向循环链表的插入操作

图四 双向链表插入流程示意图

myData *newNode = new myData;
newNode->nextNode = myNode->nextNode;
myNode_1 = myNode->nexNode;
myNode_1->previousNode = newNode;
myNode->nextNode = newNode;

双向循环链表的遍历操作

双向循环链表可以从正 反两个方向进行数据遍历,咱们就直接开始双向遍历了哈

主要是先找到headerNode,  每次遍历需要先判断currentNode是不是尾部节点(currentNode的nextNode 是不是 指向了头节点)如果不是尾部节点,直接将currentNode指向currentNode的下一个节点,如果是尾部节点,就开始反向遍历

bool isBackwardsEcho = false;/* 是否遍历到了尾部节点 */
if (currentNode->nextNode == headerNode &&headerNode->previousNode == currentNode)isBackwardsEcho = true;/* 反向遍历 */
if (isBackwardsEcho) {/* 是否反向遍历到了头部节点 */(currentNode == headerNode) ?(currentNode = nullptr)     :(currentNode = currentNode->previousNode);
} else /* 正向遍历 */currentNode = currentNode->nextNode;

双向循环链表的删除操作

双向循环链表的删除操作,也有细节点需要注意,可以参考下面的代码逻辑

myData::~myData() {
/* 析构函数 进行一些内存释放等操作 */
}myData * p = headerNode;
this->currentNode = headerNode;while (currentNode) {/* 是否只有一个节点 */if (currentNode->nextNode == nullptr) { delete currentNode;currentNode = headerNode = nullptr;/* 不是尾部节点*/} else if (currentNode->nextNode != p) {currentNode = currentNode->nextNode;delete headerNode;headerNode = currentNode;/* 是尾部节点 */} else if (currentNode->nextNode == p) {delete currentNode;currentNode = headerNode = nullptr;}
}

呈上双向链表的完整示例代码,供给小伙伴学习交流,赶紧 ctrl-c ctrl-v 测试一下吧

/********************************************************
* Description: simply C++ linked demo
* Author: jiangxiaoyu
* Data: Fir Apr 28 2023
*********************************************************/#include <iostream>
#include <string>
#include <regex>
#include <limits>
#include <ctype.h>typedef struct StaffInfo {int             ages;int             salary;int             seniority;std::string     name;std::string     post;std::string     education;void *          previousNode;void *          nextNode;~StaffInfo();
} StaffInfomation;StaffInfo::~StaffInfo() {ages = salary = seniority = 0;name = post = education = "";previousNode = nextNode = nullptr;
}class DoubleLinkedList {
public:DoubleLinkedList();void helper();bool isRegexInput(std::string str);std::string regexDigit(std::string str, std::string msg);void createLinkedList();void collectStaffInfomation(StaffInfomation *);void printStaffInfomation();void destoryStaffInfomation();void exitSystem();
private:StaffInfomation* headerNode,* currentNode;
};/* initialize member */
DoubleLinkedList::DoubleLinkedList():headerNode(nullptr),currentNode(nullptr) {
}void DoubleLinkedList::helper()
{std::cout << "nn" << std::endl;std::cout << "Simply staff information manager syatem" << std::endl;std::cout << "1) Create New Staff Information" << std::endl;std::cout << "2) Printf All Staff Information" << std::endl;std::cout << "3) Destory All Staff Information" << std::endl;std::cout << "4) Helper Manual" << std::endl;std::cout << "5) Exit" << std::endl;
}void DoubleLinkedList::collectStaffInfomation(StaffInfomation * staffInfo)
{std::cout << "-------------------------------" << std::endl;std::cout << "staff information system" << std::endl;std::cout << "nstaff name:"; std::cin >> staffInfo->name;std::cout << "nstaff ages:"; std::cin >> staffInfo->ages;std::cout << "nstaff education:"; std::cin >> staffInfo->education;std::cout << "nstaff post:"; std::cin >> staffInfo->post;std::cout << "nstaff seniority:"; std::cin >> staffInfo->seniority;std::cout << "nstaff salary:"; std::cin >> staffInfo->salary;
}void DoubleLinkedList::printStaffInfomation()
{StaffInfomation * LinkedHeader = headerNode;bool isBackwardsEcho = false;while (LinkedHeader) {std::cout << "-------------------------------" << std::endl;std::cout << "tstaff information system" << std::endl;printf("tstaff name:%sn",         LinkedHeader->name.data());printf("tstaff ages:%dn",         LinkedHeader->ages);printf("tstaff education:%sn",    LinkedHeader->education.data());printf("tstaff post:%sn",         LinkedHeader->post.data());printf("tstaff seniority:%dn",    LinkedHeader->seniority);printf("tstaff salary:%dn",       LinkedHeader->salary);std::cout << "-------------------------------" << std::endl;if (LinkedHeader->nextNode == headerNode && headerNode->previousNode == LinkedHeader) {isBackwardsEcho = true;std::cout << "=========== already traverse list =============" << std::endl;}/* backwards traverse */if (isBackwardsEcho) {/* backwards traverse all list or not */(LinkedHeader == headerNode) ?(LinkedHeader = nullptr)         :(LinkedHeader = (StaffInfomation*)LinkedHeader->previousNode);} else LinkedHeader = (StaffInfomation *)LinkedHeader->nextNode;}
}void DoubleLinkedList::createLinkedList()
{StaffInfomation * staffInfo = new StaffInfomation{0};if (!headerNode && !currentNode) {headerNode = currentNode = staffInfo;} else {headerNode->previousNode = staffInfo;currentNode->nextNode = staffInfo;staffInfo->previousNode = currentNode;staffInfo->nextNode = headerNode;currentNode = staffInfo;}collectStaffInfomation(staffInfo);
}void DoubleLinkedList::destoryStaffInfomation()
{StaffInfomation * p = headerNode;this->currentNode = headerNode;while (currentNode) {if (currentNode->nextNode == nullptr) { /* if only one node */delete currentNode;currentNode = headerNode = nullptr;} else if (currentNode->nextNode != (StaffInfomation*)p) {currentNode = (StaffInfomation*)currentNode->nextNode;delete headerNode;headerNode = currentNode;} else if ((StaffInfomation*)currentNode->nextNode == (StaffInfomation*)p) { /* if travse */delete currentNode;currentNode = headerNode = nullptr;}}
}int main(int argc, char ** argv)
{DoubleLinkedList test;do {test.helper();int cmd = 0; std::cout << "please input flag:"; std::cin >> cmd;switch (cmd) {case 1: ateLinkedList(); break;case 2: test.printStaffInfomation(); break;case 3: test.destoryStaffInfomation(); break;case 4: test.helper(); break;default: std::cout << "input invalid!" << std::endl;}} while(true);return 0;
}

创作不易,动动发财的小手点个关注再走呗

本文发布于:2024-01-31 17:34:43,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170669368630223.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据结构   双向   链表   完整   代码
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23