双向链表
基础理论
- 优点:可以方便的访问前驱结点,使用尾插法和尾删法效率就会有很大提升;
- 结点基本组成:数据域 + 一个前驱指针(指向前一个结点的指针)+ 一个后继指针;
注:数据结构系列将持续更新,欢迎交流讨论…
关于文中实现的双向链表
- 实现功能:头插法,尾插法,头删法,尾删法,特定结点删除,修改数据,打印链表;
- 组成:一个自定义系统类 + 一个包含数据、前驱指针、后继指针的结构体;
双向链表基本结构
说明:红色代表后继指针,紫色代表前驱指针
插入结点时指针的指向及先后指向
后面写的代码也是按照这个图的步骤来
实现步骤
- 定义一个结构体,包含前驱指针、后继指针、数据;
- 定义一个系统类,实现初始化头和尾结点、创建新节点、增、删、改、查等功能;
- 测试代码的正确性;
List.h代码
#pragma once
typedef struct DATA
{
int number;
DATA* Right;
DATA* Light;
}Data, * p_Data;
class System
{
public:
System();//在构造函数中头节点和尾结点初始化结点
~System();
p_Data initNode();//初始化结点
p_Data createNode(int num);//创建一个新的结点
void insertHData(int num);//头插法
void insertTData(int num);//尾插法
bool deleteNode(int num);
bool delHead();//头删法
bool delTail();//尾删法
bool ChangeData(int oldNum, int newNum);//修改数据
//查找数据并返回它的位置
int searchNode(int num);//如果有返回它在链表第几个位置,初始位置为1
int size()const;
void printList();
protected:
int m_curSize;
p_Data m_head;//头节点
p_Data m_tail;//尾结点
};
List.cpp代码
#include "List.h"
#include <iostream>
using namespace std;
System::System()
{
m_head = m_tail = initNode();
m_curSize = 0;
}
System::~System()
{
}
p_Data System::initNode()
{
p_Data newNode = new Data;
newNode->Light = newNode->Right = nullptr;
newNode->number = -1;
return newNode;
}
p_Data System::createNode(int num)
{
p_Data newCode = new Data;
newCode->number = num;
newCode->Light = newCode->Right = nullptr;
return newCode;
}
void System::insertHData(int num)
{
p_Data newNode = createNode(num);
if (m_curSize == 0)
{
m_tail->Light = newNode;
//m_head->Right = newNode;
//newNode->Light = m_head;
newNode->Right = m_tail;
}
else
{
newNode->Right = m_head->Right;
//newNode->Light = m_head;
m_head->Right->Light = newNode;
//m_head->Right = newNode;
}
newNode->Light = m_head;
m_head->Right = newNode;
m_curSize++;
}
void System::insertTData(int num)
{
p_Data newNode = createNode(num);
if (m_curSize == 0)
{
m_head->Right = newNode;
//m_tail->Light = newNode;
newNode->Light = m_head;
//newNode->Right = m_tail;
}
else
{
//newNode->Right = m_tail;
newNode->Light = m_tail->Light;
m_tail->Light->Right = newNode;
//m_tail->Light = newNode;
}
newNode->Right = m_tail;
m_tail->Light = newNode;
m_curSize++;
}
bool System::deleteNode(int num)
{
p_Data pMove = m_head->Right;
while (pMove != m_tail)
{
if (pMove->number == num)
{
pMove->Light->Right = pMove->Right;
pMove->Right->Light = pMove->Light;
delete pMove;
pMove = nullptr;
m_curSize--;
return true;
}
pMove = pMove->Right;
}
return false;
}
bool System::delHead()
{
if (m_curSize == 0)
{
return false;
}
p_Data delNode = m_head->Right;
delNode->Right->Light = m_head;
m_head->Right = delNode->Right;
delete delNode;
delNode = nullptr;
m_curSize--;
return true;
}
bool System::delTail()
{
if (m_curSize == 0)
{
return false;
}
p_Data delNode = m_tail->Light;
delNode->Light->Right = m_tail;
m_tail->Light = delNode->Light;
m_curSize--;
return true;
}
bool System::ChangeData(int oldNum, int newNum)
{
p_Data pMove = m_head->Right;
while (pMove != m_tail)
{
if (pMove->number == oldNum)
{
pMove->number = newNum;
return true;
}
pMove = pMove->Right;
}
return false;
}
int System::searchNode(int num)
{
p_Data pMove = m_head->Right;
int position = 1;
while (pMove != m_tail)
{
if (pMove->number == num)
{
return position;
}
pMove = pMove->Right;
position++;
}
return -1;
}
int System::size() const
{
return m_curSize;
}
void System::printList()
{
p_Data pMove = m_head->Right;
while (pMove != m_tail)
{
cout << pMove->number << " ";
pMove = pMove->Right;
}
}
Main.cpp主函数测试代码
#include <iostream>
#include "List.h"
using namespace std;
int main()
{
System sys;
sys.insertHData(1);
sys.insertHData(2);
sys.insertHData(3);
sys.insertTData(4);
sys.insertTData(5);
sys.insertTData(6);
sys.printList();
cout << endl;
sys.ChangeData(3, 13);
sys.printList();
cout << endl;
sys.deleteNode(6);
sys.printList();
cout << endl;
sys.delHead();
sys.printList();
cout << endl;
sys.delTail();
sys.printList();
cout << endl;
cout << sys.searchNode(5) << endl;
cout << sys.size() << endl;
return 0;
}
注:数据结构系列将持续更新,仅是个人所学展示,如有误还请不吝赐教,欢迎交流讨论…