我认为是最简单的c++实现线性表中链表相关过程
来源:互联网 发布:破解收费辅助软件 编辑:程序博客网 时间:2024/05/22 14:01
这是链表的,虽然代码有点长,但这只是为了规范化才这样写的,每行代码都有详细注释:我认为这是我见过最简单的链表了,小白完全看的懂,大神勿喷
如果不会的给我留言
第一个是线性表类:List.h
class List
{public:
List();//链表不需要声明长度,而是动态在内存中开辟空间
~List();//析构函数,用来回收内存
void ClearList();//清空链表,清空存储了数据的结点
bool ListEmpty();//判断链表是否为空
bool ListInsert(int i, Node *n);//将节点插入到指定位置
bool getElem(int i,Node *n);//根据位序查找指定元素
bool ListDelete(int i, Node * n);//根据位序删除指定节点
int LocateElem(Node *n);//根据元素找到对应的序号
void ListTraverse();//遍历链表
bool ListInsertFirst(Node *n);//往首元结点插入数据
bool priorElem(Node *pCurrNode , Node *pPreElem);//查询指定节点的前驱
bool afterElem(Node *pCurrNode, Node *pPreElem);//查询指定节点的后继
Node *list;//节点指针
//不需要长度
int length;//存储的元素个数
};
#endif // !LIST
第二个头文件:节点类.h
#ifndef NODE
#define NODE
//节点类
class Node
{
public:
int data;//数据域
Node *next;//指针域,用于指向下一个节点
void printNode();//节点数据输出
};
#endif // !Node
实现:
#include"节点类.h"
#include"List.h"
#include<iostream>
using namespace std;
void Node::printNode()//将数据输出
{
cout << data << endl;
}
List::List()
{
//首先创建一个头结点,然后通过头结点来操作整个链表
list = new Node;//从堆中申请动态内存
list->data = 0;//头结点的数据域没有意义
list->next = NULL;//先让其默认指向空
length = 0;//没有存储数据的节点
}
List::~List()
{
//将链表中的所有节点包括头结点释放
//先清空链表
ClearList();
delete list;//将头结点删除
list = NULL;//将头结点清空
}
void List::ClearList()
{
length = 0;//将存储数据的个数设置为0
Node *curr = list->next;//将头结点的指针临时存储
while (curr != NULL)//当最后一个节点的指针域不指向空时(也就是不是最后一个节点时)
{
//使用一个临时变量存储下一个节点
Node *temp = curr->next;
delete curr;//将当前节点删除
curr = temp;//将当前节点的下一个节点赋值给当前节点
}
list->next = NULL;//让头结点指向为空
}
bool List:: ListEmpty()//判断链表是否为空
{
if (list->next == NULL)
{
return true;
}
else
return false;
}
bool List::ListInsert(int i, Node *n)//往链表中插入数据
{
//判断i是否合法
if (i<0 || i>length)
{
return false;
}
//将头结点作为当前节点
Node *curr = list;
Node *currBefore = NULL;//前驱节点
for (size_t k = 0; k <= i; k++)//按顺序将当前节点往后移动
{
currBefore = curr;//将当前节点往后移动一次,他的前驱指向他原来的位置
curr = curr->next;//将当前节点往后移
}
//创建一个新的节点来插入
Node *newNode = new Node;
//将新创建的节点指向位序为i的节点
newNode->data = n->data;
newNode->next = curr;
currBefore->next = newNode;
length++;
return true;
}
void List::ListTraverse()//遍历链表(输出)
{
Node *curr = list;
while (curr->next != NULL)
{
curr = curr->next;
curr->printNode();
}
}
bool List::ListInsertFirst(Node *n)//插入到首元结点
{
Node *newNode = new Node;
newNode->data = n->data;
if (list->next == NULL)
{
list->next = newNode;
}
else
{
Node *temp = list->next;
newNode->next = temp;
list->next = newNode;
}
length++;//长度增加
return true;
}
bool List::getElem(int i, Node *n)//根据位序获取链表中的元素
{
if (i<0 || i>length)
{
return false;
}
//从头结点往后遍历
Node *curr = list;
for (size_t k = 0; k <= i; k++)
{
curr = curr->next;
}
n->data = curr->data;
return true;
}
bool List::ListDelete(int i, Node *n)//删除节点
{
if (i<0 || i>length)
{
return false;
}
Node *curr = list;
Node *currBefore = NULL;
for (size_t k = 0; k <= i; k++)
{
currBefore = curr;
curr = curr->next;
}
n->data = curr->data;
Node *currAfter = curr->next;
//将当前节点删除
delete curr;
//将当前节点的前驱指向当前节点的后继
currBefore->next = currAfter;
length--;
return true;
}
bool List::priorElem(Node *pCurrNode, Node *pPreElem)//获取指定节点的前驱节点
{
Node *temp = new Node;
Node *curr = list;//将头结点设为当前节点
while (curr->next != NULL)
{
temp = curr;
curr = curr->next;
if (curr->data == pCurrNode->data)
{
pPreElem->data = temp->data;
cout << "指定节点的前驱节点pPreElem = " << temp->data << endl;
}
}
return true;
}
bool List::afterElem(Node *pCurrNode, Node *pPreElem)//获取指定节点的后继节点
{
Node *temp = new Node;
Node *curr = list;
while (curr->next != NULL)
{
temp = curr;
curr = curr->next;
if (temp->data == pCurrNode->data)
{
pPreElem->data = curr->data;
cout << "指定节点的后继节点afterElem = " << pPreElem->data << endl;
}
}
if (curr->next == NULL)
{
cout << "这个节点没有后继节点!" << endl;
return false;
}
return true;
}
int List::LocateElem(Node *n)//查找指定节点的位序
{
int a = 0;
Node *curr = list;
while (curr->next != NULL)
{
a++;
curr = curr->next;
if (curr->data == n->data)
{
cout <<"该节点的位序是:"<< a << endl;
}
}
return a;
}
测试:
#include"List.h"
#include<conio.h>
using namespace std;
int main()
{
List *L = new List();
Node n1;
char d = 'ss';
n1.data = 1;
Node n2;
n2.data = 2;
Node n3;
n3.data = 3;
Node n4;
n4.data = 4;
Node n5;
n5.data = 5;
L->ListInsert(0, &n1);
L->ListInsert(1, &n2);
L->ListInsert(2, &n3);
L->ListInsert(3, &n4);
L->ListInsert(4, &n5);
L->ListTraverse();
L->priorElem(&n3, &n1);
L->afterElem(&n5, &n1);
L->LocateElem(&n3);
getch();
}
- 我认为是最简单的c++实现线性表中链表相关过程
- 我认为是最简单的c++实现线性表中顺序表相关过程
- 圆角的实现(用最简单的方法,我认为是这样)
- 我认为这是世上最经典的15句话.....
- c语言实现最简单的哈希表(开放地址线性探测法)
- SQL2008安装提示"Microsoft visual studio 2008早期之前的版本"解决(这是我认为最简单有效的方法)
- js 交换赋值我认为最简单的方法 (ES6解构)
- 转发一篇关于ANSI,Unicode,UTF-8编码的文章,我认为是最容易动的,最详细的
- 简单c实现无头单链表的相关操作
- 我认为最节省资源的系统安全方案
- C语言固定大小的线性表的简单实现
- 存储过程的简单实现[C#]
- 我认为比较好的分页存储过程
- 我认为比较好的分页存储过程
- 我认为比较好的分页存储过程
- [ASP.net(C#)]最简单的一个存储过程
- 可能是Android最简单的欢迎页面实现
- 最简单的数据结构----线性表
- MySQL事务隔离级别详解
- 1036. 跟奥巴马一起编程(15) PAT乙级真题
- express 学习记录
- 6.5抽象类
- linux lsof详解
- 我认为是最简单的c++实现线性表中链表相关过程
- QT使用OPENGL的心得
- Spring下载各版本jar包
- Python实现批量处理文件的缩进和转码问题
- 先码后看 Tomcat怎么启动容器的——Boostrap篇 侵立删
- Linux安装最优方法
- java 中的管理项目注释TODO FIXME XXX
- 浅谈 Spring 框架注解的用法分析
- 通过cmd连接数据库时报错协议适配器错误